hibernate
Chargement paresseux vs Eager Chargement
Recherche…
Chargement paresseux vs Eager Chargement
La récupération ou le chargement de données peut être principalement classé en deux types: avide et paresseux.
Pour utiliser Hibernate, assurez-vous d’ajouter la dernière version à la section dépendances de votre fichier pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
1. Chargement rapide et chargement paresseux
La première chose que nous devrions discuter ici est ce que le chargement paresseux et le chargement rapide sont:
Le chargement rapide est un modèle de conception dans lequel l'initialisation des données se produit sur place. Cela signifie que les collections sont récupérées complètement au moment où leur parent est récupéré (à récupérer immédiatement)
Le chargement différé est un motif de conception utilisé pour différer l'initialisation d'un objet jusqu'au point où il est nécessaire. Cela peut contribuer efficacement à la performance de l'application.
2. Utilisation des différents types de chargement
Le chargement différé peut être activé à l'aide du paramètre XML suivant:
lazy="true"
Laissez-nous plonger dans l'exemple. Nous avons d'abord une classe d'utilisateurs:
public class User implements Serializable {
private Long userId;
private String userName;
private String firstName;
private String lastName;
private Set<OrderDetail> orderDetail = new HashSet<>();
//setters and getters
//equals and hashcode
}
Regardez l’ensemble de commandes que nous avons. Regardons maintenant la classe OrderDetail :
public class OrderDetail implements Serializable {
private Long orderId;
private Date orderDate;
private String orderDesc;
private User user;
//setters and getters
//equals and hashcode
}
La partie importante de la configuration du chargement UserLazy.hbm.xml
dans UserLazy.hbm.xml
:
<set name="orderDetail" table="USER_ORDER" inverse="true" lazy="true" fetch="select">
<key>
<column name="USER_ID" not-null="true" />
</key>
<one-to-many class="com.baeldung.hibernate.fetching.model.OrderDetail" />
</set>
Voici comment le chargement différé est activé. Pour désactiver le chargement différé, nous pouvons simplement utiliser: lazy = "false"
, ce qui permettra un chargement rapide. Voici l'exemple de la configuration du chargement dans un autre fichier User.hbm.xml:
<set name="orderDetail" table="USER_ORDER" inverse="true" lazy="false" fetch="select">
<key>
<column name="USER_ID" not-null="true" />
</key>
<one-to-many class="com.baeldung.hibernate.fetching.model.OrderDetail" />
</set>
Portée
Pour ceux qui n'ont pas joué avec ces deux conceptions, la portée de paresseux et avide se situe dans une session spécifique de SessionFactory . Désireux de tout charger instantanément, cela signifie qu'il n'est pas nécessaire d'appeler pour le récupérer. Mais la récupération différée requiert généralement une action pour récupérer une collection / un objet mappé. Cela pose parfois des problèmes pour récupérer paresseux en dehors de la session . Par exemple, vous avez une vue qui montre les détails de certains POJO mappés.
@Entity
public class User {
private int userId;
private String username;
@OneToMany
private Set<Page> likedPage;
// getters and setters here
}
@Entity
public class Page{
private int pageId;
private String pageURL;
// getters and setters here
}
public class LazzyTest{
public static void main(String...s){
SessionFactory sessionFactory = new SessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
User user = session.get(User.class, 1);
transaction.commit();
session.close();
// here comes the lazy fetch issue
user.getLikedPage();
}
}
Lorsque vous essaierez d'être récupéré paresseux en dehors de la session, vous obtiendrez l' exception lazyinitializeException . En effet, par défaut, la stratégie de récupération pour tous les oneToMany ou toute autre relation est paresseuse (appel à la base de données à la demande) et lorsque vous fermez la session, vous ne pouvez plus communiquer avec la base de données. notre code essaie donc de récupérer la collection de likedPage et il génère une exception car il n'y a pas de session associée pour le rendu de la base de données.
La solution consiste à utiliser:
- Session ouverte dans la vue - Dans laquelle vous gardez la session ouverte même sur la vue rendue.
-
Hibernate.initialize(user.getLikedPage())
avant la fermeture de la session -Hibernate.initialize(user.getLikedPage())
à hibernate d'initialiser les éléments de la collection