IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

enregistrement d'un fichier dans un blob


Sujet :

Hibernate Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 38
    Points : 32
    Points
    32
    Par défaut enregistrement d'un fichier dans un blob
    bonjour,

    je vous explique mon problème :
    j'ai une table qui contient un champs de type BLOB (oracle)
    je veux enregistrer un fichier dans ce blob, j'ai donc un formulaire avec un champs de type FormFile (Struts), à partir de ce champs je crée le blob associé à l'aide de la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Blob blob = hibernate.createBlob(_form.getDescriptionFile().getInputStream());
    puis j'enregistre l'objet dans la base de données.
    J'ai alors l'exception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    java.sql.SQLException: opération interdite: streams type cannot be used in batching
    	at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
    	at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
    	at oracle.jdbc.driver.OraclePreparedStatement.addBatch(OraclePreparedStatement.java:4073)
    	at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:29)
    	at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:1982)
    Ce qui est vraiment "bizarre" c'est que cette exception n'est pas levée pour les fichier texte ou gif mais elle est levée pour les fichiers jpg, html et doc par exemple.

    Si quelqu'un à une idée....

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 38
    Points : 32
    Points
    32
    Par défaut
    j'ai ajouté cette ligne dans le fichier "hibernate.cfg.xml"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <property name="hibernate.jdbc.batch_size">0</property>
    l'exception n'est plus levée lors de l'update mais le blob n'est pas enregistré dans la table et lors de l'insertion j'ai une autre exception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     java.sql.SQLException: Il n'y a plus de données à lire dans le socket
    un peu d'aide serait vraiment la bienvenue

  3. #3
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Comment as tu mappé ton blob dans ton objet, montre nopus ton fichier de mapping ça nous parlera peut être un peu plus. Usuellement, je mappe mes blobs sous forme de tableau de byte
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 38
    Points : 32
    Points
    32
    Par défaut
    je mappe mon blob comme çà
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <property name="description"
                  column="DESC_VERSION_LOGICIEL"
                  type="blob"/>
    si je le mappe comme tu dis avec un tableau de byte j'ai l'exception suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java.sql.SQLException: La taille des données est supérieure à la taille max. pour ce type: 24064
    il me semblait que la taille des données était de 4Go

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 38
    Points : 32
    Points
    32
    Par défaut
    en ajoutant les deux lignes suivantes dans le fichier hibernate.cfg.xml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    <property name="hibernate.jdbc.batch_size">0</property>
    <property name="hibernate.jdbc.use_streams_for_binary">true</property>
    je n'ai plus l'exception précédente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java.sql.SQLException: La taille des données est supérieure à la taille max. pour ce type: 24064
    mais par contre mes fichiers contiennent que des carrés

    comment faut-il faire pour que les données contenus dans le byte[] soient lu correctement?

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 38
    Points : 32
    Points
    32
    Par défaut
    problème résolu
    pour info : la limitation des données pour les blobs était due au driver utilisé (thin)

  7. #7
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Bonjour,

    je reviens sur ce post car je rencontre le même problème cité plus haut, et je n'arrive pas à y trouver une solution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java.sql.SQLException: La taille des données est supérieure à la taille max. pour ce type
    J'utilise Ibatis 2.3, Oracle 9 et java 1.4.

    S'agit-il d'un problème de drivers comme l'indique le dernier post et si oui, quelle version de drivers dois-je utiliser afin de résoudre ce problème de taille de donnée ? Actuellement j'utilise les "classes12", mais j'ai effectué des tests non concluants avec "ojdbc14.jar" et "ojdbc5.jar". J'ai aussi modifié ma déclaration de datasource de "thin" vers "oci9" mais cela ne donne pas plus de résultat.

    Quelqu'un aurait-il une idée ?

    Si vous avez besoin de précision supplémentaire, n'hésitez pas

    Merci d'avance

  8. #8
    Expert éminent
    Avatar de elitost
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2003
    Messages
    1 985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 985
    Points : 6 566
    Points
    6 566
    Par défaut
    Citation Envoyé par so007 Voir le message
    problème résolu
    pour info : la limitation des données pour les blobs était due au driver utilisé (thin)
    +1 pour un peu plus d'explication

  9. #9
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2006
    Messages : 60
    Points : 52
    Points
    52
    Par défaut
    je relance le sujet, je rencontre le même problème...

    Help me!!!!

  10. #10
    Expert éminent
    Avatar de elitost
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2003
    Messages
    1 985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 985
    Points : 6 566
    Points
    6 566
    Par défaut
    De nôtre côté on a ce genre de truc, un custom type Hibernate :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.Serializable;
    import java.sql.Clob;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Types;
    import java.sql.Blob;
     
    import oracle.jdbc.OracleConnection;
    import oracle.sql.BLOB;
     
    import org.hibernate.Hibernate;
    import org.hibernate.HibernateException;
    import org.hibernate.usertype.UserType;
    import org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor;
     
    public class BlobUserType implements UserType {
        public int[] sqlTypes() {
    	return new int[] { Types.BLOB };
        }
     
        public Class returnedClass() {
    	return byte[].class;
        }
     
        public boolean equals(Object x, Object y) {
    	return (x == y) || (x != null && y != null && java.util.Arrays.equals((byte[]) x, (byte[]) y));
        }
     
        public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
    	Blob blob = rs.getBlob(names[0]);
    	return blob.getBytes(1, (int) blob.length());
        }
     
        protected OracleConnection findOracleConnection(Connection orig) throws ClassNotFoundException {
    	if (orig instanceof OracleConnection)
    	    return (OracleConnection) orig;
     
    	CommonsDbcpNativeJdbcExtractor extractor = new CommonsDbcpNativeJdbcExtractor();
    	try {
    	    //return (OracleConnection) extractor.getNativeConnection(orig);
    	    return (OracleConnection) extractor.getNativeConnection(orig);
    	} catch (SQLException sql) {
    	    throw new HibernateException("JDBC connection object must be a oracle.jdbc.OracleConnection. " + "Connection class is " + orig.getClass().getName());
    	}
        }
     
        public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
    	try {
    	    Connection conn = st.getConnection();
    	    // Make sure connection object is right type
    	    conn = this.findOracleConnection(conn);
     
    //	    if (st instanceof oracle.jdbc.OraclePreparedStatement) {
    		oracle.sql.BLOB blob = oracle.sql.BLOB.createTemporary(conn, false, oracle.sql.BLOB.DURATION_SESSION);
     
    		blob.open(BLOB.MODE_READWRITE);
     
    		OutputStream out = blob.getBinaryOutputStream();
     
    		out.write((byte[]) value);
    		out.flush();
    		out.close();
     
    		blob.close();
     
    		//((oracle.jdbc.OraclePreparedStatement) (st)).setBLOB(index, blob);
    		st.setBlob( index, (Blob)blob );
    //	    } else {
    //
    		//st.setBlob(index, Hibernate.createBlob((byte[]) value));
    //	    }
    	} catch (ClassNotFoundException e) {
    	    // could not find the class with reflection
    	    throw new HibernateException("Unable to find a required class.\n" + e.getMessage());
    	} catch (IOException e) {
    	    throw new SQLException("failed write to blob" + e.getMessage());
    	}
     
        }
     
        public Object deepCopy(Object value) {
    	if (value == null)
    	    return null;
     
    	byte[] bytes = (byte[]) value;
    	byte[] result = new byte[bytes.length];
    	System.arraycopy(bytes, 0, result, 0, bytes.length);
     
    	return result;
        }
     
        public boolean isMutable() {
    	return true;
        }
     
        public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
    	// TODO Auto-generated method stub
    	return null;
        }
     
        public Serializable disassemble(Object arg0) throws HibernateException {
    	// TODO Auto-generated method stub
    	return null;
        }
     
        public int hashCode(Object arg0) throws HibernateException {
    	// TODO Auto-generated method stub
    	return 0;
        }
     
        public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
    	// TODO Auto-generated method stub
    	return null;
        }
     
    }

    La propriété dans le mapping XML est :

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ...
    <property name="buffer" column="CONTENT"
    			type="dgt.tss.filesystem.impl.provider.db.BlobUserType" />...

    Et un tableau de bytes en attribut de la classe mappée :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ...
        private byte[] buffer;
    ...

    On a trouvé cette solution sur le site http://www.hibernate.org , ici je crois :
    http://www.hibernate.org/56.html

    A+

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 64
    Points : 46
    Points
    46
    Par défaut
    Bonjour all,

    Je relance ce sujet car je rencontre un problème dont je ne comprend pas l'origine lors de l'insertion d'un fichier dans un blob.

    Le contexte: Oracle 9i, Hibernate 3.4.0.GA, classes persistantes sous forme d'EJB3 Entity, serveur d'appli Resin 3.2.1, driver JDBC ojdbc14 10.2.0.1.0

    Quand j'essaie d'enregistrer un fichier de petite taille (< 4Ko, + ou -), ça passe, mais dès que le fichier dépasse cette taille, j'ai l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    java.sql.SQLException: Exception d'E/S: End of TNS data channel
    	at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
    	at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
    	at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:334)
    	at oracle.jdbc.ttc7.TTC7Protocol.handleIOException(TTC7Protocol.java:3668)
    	at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1986)
    	at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1119)
    	at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2191)
    	at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2064)
    	at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2989)
    	at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:658)
    	at com.caucho.sql.UserPreparedStatement.executeUpdate(UserPreparedStatement.java:107)
    	at com.caucho.sql.UserPreparedStatement.executeUpdate(UserPreparedStatement.java:107)
    	at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
    	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2275)
    	... 45 more
    Ci-dessous un extrait de l'EJB entity correspondant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Entity
    @Table(name = "MA_TABLE", schema = "SCHEMA")
    public class MessAttachmentLog implements java.io.Serializable {
    	// ...
     
    	private byte[] file;
     
    	@Column(name = "LE_FICHIER")
    	@Lob
    	public byte[] getFile() { return this.file; }
     
    	public void setFile(byte[] file_) { this.file = file_; }
     
    	// ...
    }
    L'extrait du script de création de la table:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE SCHEMA.MA_TABLE (
      -- ...
     
      LEP_FILE BLOB,
     
      -- ...
    )
    Si ça vous parle, n'hésitez pas, parce que j'avoue être dépassé par les événements ! D'avance merci

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 64
    Points : 46
    Points
    46
    Par défaut
    Bon ben problème résolu

    Le souci venait de l'utilisation du driver thin, en passant au driver oci, ça passe nickel !

  13. #13
    Expert éminent
    Avatar de elitost
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2003
    Messages
    1 985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 985
    Points : 6 566
    Points
    6 566
    Par défaut
    Pourrais tu poster ton code ici ? afin de voir comment tu gères les blobs de ton côté ?

    Merci d'avance

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 64
    Points : 46
    Points
    46
    Par défaut
    Avec plaisir Je précise quand même que tout se fait avec des EJB3 et non par un mapping Hibernate "à l'ancienne"...

    1èrement, ma classe persistante, telle que décrite lors de mon précédent post:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Entity
    @Table(name = "MA_TABLE", schema = "SCHEMA")
    public class MessAttachmentLog implements java.io.Serializable {
    	// ...
     
    	private byte[] file;
     
    	@Column(name = "LE_FICHIER")
    	@Lob
    	public byte[] getFile() { return this.file; }
     
    	public void setFile(byte[] file_) { this.file = file_; }
     
    	// ...
    }
    Après, la persistance est gérée par Hibernate via l'entity manager au sein d'un session bean...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Stateless
    public class MessagingBean implements IMBeanLocal, IMBeanRemote {
    	@PersistenceContext
    	private EntityManager entityManager;final MessAttachmentLog
     
    	private final void logMessage() {
    		final MessAttachmentLog msgLogAttach = new MessAttachmentLog ();
    		final byte[] file = ... // récupération du fichier sous forme d'un byte[]
     
    		msgLogAttach.setFile(file);
     
    		entityManager.persist(msgLogAttach);
    		entityManager.flush();
    	}
    }

  15. #15
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2006
    Messages : 60
    Points : 52
    Points
    52
    Par défaut
    problème aussi résolu pour moi,
    c'était ma version du jar ojdbc-14.jar qui n'était pas bonne..

  16. #16
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par ptitom1381 Voir le message
    problème aussi résolu pour moi,
    c'était ma version du jar ojdbc-14.jar qui n'était pas bonne..
    je travaille aussi avec ojdbc-14.jar et j'ai eu la meme erreure
    vers quel version as tu migrés

  17. #17
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Citation Envoyé par riadhhwajdii Voir le message
    je travaille aussi avec ojdbc-14.jar et j'ai eu la meme erreure
    vers quel version as tu migrés
    La dernière, celle que tu peux télécharger sur le site d'oracle en fonction de la version d'oracle que tu utilises bien sur. http://www.oracle.com/technology/sof...dbc/index.html
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. enregistrement d'un fichier dans la memoire
    Par bobkorn dans le forum Langage
    Réponses: 1
    Dernier message: 21/04/2008, 18h33
  2. [BLOB]Charger un fichier dans un BLOB
    Par elitost dans le forum SQL
    Réponses: 0
    Dernier message: 07/02/2008, 12h29
  3. Insertion d'un fichier dans un BLOB qui ne marche pas
    Par Invité dans le forum SQL Procédural
    Réponses: 7
    Dernier message: 15/11/2007, 19h57
  4. Inserer un fichier dans un Blob?
    Par phpaide dans le forum JDBC
    Réponses: 3
    Dernier message: 05/07/2007, 12h01
  5. Réponses: 6
    Dernier message: 23/11/2006, 16h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo