Attention, je partage ici un un mémo personnel, car je pense qu'il peut être utile. Le vocabulaire n'est pas forcément académiquement correct, si vous trouvez des coquilles, vos commentaires sont les bienvenus. Pour comprendre ce qui suit, vous devez être familier avec Hibernate!

Pour stocker dans MySQL des gros blobs, jusqu'à 2Go, il faut utiliser les types LONGBLOB et LONGTEXT, car les blobs de base sont limités à 64ko.

Dans Hibernate Annotations, pour la définition d'un blob dans une entitée (@Entity), il ne faut donc pas utiliser l'annotation @Lob, mais à la place @Column(columnDefinition="LONGBLOB") pour du binaire, ou @Column(columnDefinition="LONGTEXT") pour du texte.

Par exemple:

  @Entity
  public class Revision implements Serializable {
     Long  id;
     Date creationDate = new Date ();
     String creationComment;
     byte  binaryContent;
     String textualContent;
     @Id
     @GeneratedValue
     public Long getId () {
        return id;
     }
     public void setId (Long id) {
        this.id = id;
     }
     @Temporal(TemporalType.TIMESTAMP)
     public Date getCreationDate () {
        return creationDate;
     }
     public void setCreationDate (Date creationDate) {
        this.creationDate = creationDate;
     }
     public String getCreationComment () {
        return creationComment;
     }
     public void setCreationComment (String creationComment) {
        this.creationComment = creationComment;
     }
     @Column(columnDefinition="LONGBLOB")
     public byte getBinaryContent () {
        return binaryContent;
     }
     public void setBinaryContent (byte binaryContent) {
        this.binaryContent = binaryContent;
     }
     @Column(columnDefinition="LONGTEXT")
     public String getTextualContent () {
        return textualContent;
     }
     public void setTextualContent (String textualContent) {
        this.textualContent = textualContent;
     }
  }

Quand une entitée est chargée par Hibernate, tous ses attributes sont récupérés depuis la base de données (Eager loading). Donc si cette entitée contient des blobs, tous les blobs seront lus. Inutile de vous dire que cela peut rapidement mettre à genou la base de données, même la rapide MySQL.

Pour corriger ce problème, il existe deux solutions. La première consiste à créer pour chaque blob un entitée, car le chargement des collections (les liens entre les objets, comme les pointeurs, vecteurs, etc etc) est dynamique (Lazy loading).

La seconde solution consiste à activer le chargement dynamique des attributs. Il faut pour cela spécifier ledits attributs par une annotation.

  ...
  @Basic(fetch=FetchType.LAZY)
  @Column(columnDefinition="LONGBLOB")
  ...
  @Basic(fetch=FetchType.LAZY)
  @Column(columnDefinition="LONGTEXT")
  ...

Mais cela ne suffit pas : si le code n'est pas instrumenté (=bytecode passé à une moulinette spéciale), l'annotation est SILENCIEUSEMENT IGNOREE. Pour l'instrumentation, une tâche Ant est fournie. Pour l'utiliser, par exemple:

  <target name="instrument">
     <taskdef name="instrument" classname="org.hibernate.tool.instrument.cglib.InstrumentTask">
        <classpath refid="l'id de la définition du classpath avec les .jar"/>
     </taskdef>
     <instrument verbose="true">
        <fileset dir="le dossier où sont les .class à instrumenter">
           <include name="*.class"/>
        </fileset>
     </instrument>
  </target>

Nota: Le MySQL de la Mandriva 2006 a un bug, il faut l'utiliser avec le driver JDBC Connector/J 3.0.17 et pas une version supérieure! (j'ai perdu une demi-journée avant de trouver le problème...)