web-dev-qa-db-fra.com

À quoi sert l'annotation Hibernate @LazyCollection

J'ai 2 entités en tant que parent et enfant en tant que relation OneToMany en tant que

@Entity
public class Parent {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

private String name;

@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
@IndexColumn(name = "index", base = 1)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@LazyCollection(LazyCollectionOption.EXTRA)
private List<Child> childs = new ArrayList<Child>();
// getter and setter

}

Alors, à quoi sert @ LazyCollection (LazyCollectionOption.EXTRA) et quand cela apparaîtra-t-il, comme pour quelle opération avec la liste des enfants, ce sera bénéfique?

31
Rahul Agrawal

Pour vous donner un indice, c'est principalement pour des raisons de performances, vous pouvez commencer à lire les liens suivants:

Cache de deuxième nivea

Documentation Hibernate

8
Maddy

EXTRA = .size () et .contains () n'initialiseront pas toute la collection

TRUE = initialise toute la collection au premier accès

FALSE = Chargement avide

31
wutzebaer

C'est une très bonne question, j'ai donc décidé de transformer cette réponse en article aussi .

Il n'y a en fait aucune raison d'utiliser @LazyCollection.

Les valeurs TRUE et FALSE ne sont pas nécessaires car le même comportement peut être obtenu avec le JPA FetchType.LAZY Ou FetchType.EAGER .

La valeur EXTRA n'a pas d'équivalent dans JPA et a été conçue pour les très grandes collections. Lorsque vous accédez à une collection paresseuse EXTRA pour la première fois, la collection n'est pas entièrement chargée, comme c'est généralement le cas avec toute collection JPA.

Au lieu de cela, chaque élément est récupéré un par un, à l'aide d'un SELECT secondaire. Cela peut sembler une optimisation, mais ce n'est pas parce que les collections paresseuses EXTRA sont sujettes à problèmes de requête N + 1 .

Notez que cela ne fonctionne que pour les collections ordonnées, List (s) annotées avec @OrderColumn Ou Map (s). Pour les sacs (par exemple, les List (s) normales d'entités qui ne préservent pas un certain ordre), la @LazyCollection( LazyCollectionOption.EXTRA ) se comporte comme toute autre collection LAZY (la collection est récupérée entièrement lors de son premier accès).

Si vous avez une très grande collection, vous ne devriez pas du tout la cartographier. Au lieu de cela, vous devez mapper uniquement le côté @ManyToOne Et, au lieu d'une collection côté parent, vous devez utiliser une requête JPQL paginée.

Les requêtes JPQL sont beaucoup plus faciles à ajuster car vous pouvez appliquer n'importe quel critère de filtrage et paginer l'ensemble de résultats.

18
Vlad Mihalcea