2.1 option de récupération

Les développeurs d'Hibernate connaissent depuis longtemps le problème du chargement des entités enfants. Donc, la première chose qu'ils ont faite a été d'ajouter un paramètre de récupération spécial aux annotations @OneToMany, @ManyToMany.

Ce paramètre peut prendre deux valeurs :

  • DÉSIREUX
  • PARESSEUX

Exemple:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")

Si le paramètre fetch est égal à EAGER , alors lorsque l'entité parent est chargée, toutes ses entités enfants seront également chargées. De plus, Hibernate essaiera de le faire dans une requête SQL, générant une requête lourde et obtenant toutes les données en même temps.

Si le paramètre fetch prend la valeur LAZY , alors lorsque l'entité parent est chargée, l'entité enfant ne sera pas chargée. Au lieu de cela, un objet proxy sera créé.

Avec l'aide de cet objet proxy, Hibernate suivra l'accès à cette entité enfant et la chargera en mémoire lors du premier accès.

Si nous rappelons notre situation avec des commentaires :


@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;
 
   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   @JoinColumn(name = "user_id")
   public List<Comment> comments;
}

Alors vous avez un "choix chic":

Si fetch = FetchType.EAGER, alors Hibernate chargera tous les commentaires sur la 1ère ligne de code :

User user = session.get(User.class, 1);		//load all comments here
List<Comment> comments = user.getComments();

Si fetch = FetchType.LAZY, alors Hibernate chargera tous les commentaires sur la 2ème ligne de code :

User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); //load all comments here

Comme vous pouvez déjà le deviner, vous n'avez pas d'option quand il ne charge pas tous les commentaires :)

2.2 Valeur par défaut

Si vous ne spécifiez pas d'option de récupération pour l' @ManyToannotation ..., alors Hibernate utilisera les valeurs par défaut.

Ils sont légèrement différents pour différents types d'annotations. Pour les annotations @OneToOneet @ManyToOneest EAGER, pour les annotations @OneToManyet @ManyToManyest LAZY. C'est facile à retenir - si nous nous référons à un objet, il sera complètement chargé. Si nous nous référons à une collection, elle sera chargée la première fois qu'elle sera consultée.

2.3 Annotation @LazyCollection

Comme vous l'avez déjà vu, le paramètre fetch n'aide pas beaucoup lorsque vous travaillez avec des collections. Les créateurs d'Hibernate ont essayé de résoudre ce problème en ajoutant une annotation spéciale @LazyCollection. Il est généralement écrit comme ceci :

@LazyCollection(LazyCollectionOption.TRUE)

Vous devez le spécifier lors du mappage des champs de collection :


@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;
 
   @OneToMany(cascade = CascadeType.ALL)
   @LazyCollection(LazyCollectionOption.TRUE)
   public List<Comment> comments;
}

Cette annotation a un paramètre de valeur qui peut prendre l'une des trois valeurs suivantes :

  • LazyCollectionOption. VRAI
  • LazyCollectionOption. FAUX
  • LazyCollectionOption. SUPPLÉMENTAIRE

Les deux premières options sont très similaires à l'option de récupération.

Si le paramètre est défini sur LazyCollectionOption.TRUE, cela signifie que les valeurs du champ commentaires ne seront pas chargées depuis la base de données lors du chargement de l'objet Utilisateur parent. Les objets de type Commentaire seront chargés lors du premier accès au champ de commentaires. En fait, c'est l'équivalent du paramètreFetchType.LAZY

Si le paramètre est défini sur LazyCollectionOption.FALSE, cela signifie que les valeurs du champ commentaires seront chargées depuis la base de données au moment du chargement de l'objet Utilisateur parent. Les objets de type Commentaire seront chargés lors du premier accès au champ de commentaires. En fait, c'est l'équivalent du FetchType.EAGER.