hibernate
Faules Laden gegen eifriges Laden
Suche…
Faules Laden gegen eifriges Laden
Das Abrufen oder Laden von Daten kann hauptsächlich in zwei Typen unterteilt werden: eifrig und faul.
Um den Ruhezustand zu verwenden, fügen Sie die neueste Version zum Abschnitt "Abhängigkeiten" Ihrer Datei "pom.xml" hinzu:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
1. Eifriges Laden und faules Laden
Das erste, was wir hier besprechen sollten, ist, was faules Laden und eifriges Laden sind:
Eager Loading ist ein Entwurfsmuster, bei dem die Dateninitialisierung vor Ort erfolgt. Dies bedeutet, dass Sammlungen zum Zeitpunkt des Abrufs des übergeordneten Elements vollständig abgerufen werden (sofort abrufen).
Lazy Loading ist ein Entwurfsmuster, mit dem die Initialisierung eines Objekts bis zu dem Punkt verschoben wird, an dem es benötigt wird. Dies kann effektiv zur Leistung der Anwendung beitragen.
2. Verwenden der verschiedenen Arten des Ladens
Lazy Loading kann mit folgenden XML-Parametern aktiviert werden:
lazy="true"
Lassen Sie uns in das Beispiel eintauchen. Zuerst haben wir eine Benutzerklasse:
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
}
Schauen Sie sich den Satz von orderDetail an, den wir haben. Schauen wir uns nun die OrderDetail-Klasse an :
public class OrderDetail implements Serializable {
private Long orderId;
private Date orderDate;
private String orderDesc;
private User user;
//setters and getters
//equals and hashcode
}
Der wichtige Teil, der zum Einstellen des Lazy-Ladens in der 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>
So wird das Lazy Loading aktiviert. Um das Lazy-Loading zu deaktivieren, können Sie einfach Folgendes verwenden: lazy = "false"
und dies wird das eifrige Laden ermöglichen. Das folgende Beispiel zeigt das Einrichten des Ladevorgangs in einer anderen Datei 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>
Umfang
Für diejenigen, die nicht mit diesen beiden Designs gespielt haben, liegt der Geltungsbereich von Faulheit und Eifer innerhalb einer bestimmten SessionFactory- Sitzung . Eager lädt alles sofort, dh Sie müssen nichts aufrufen, um es abzurufen. Faules Abrufen erfordert jedoch normalerweise eine Aktion, um eine zugeordnete Sammlung / ein Objekt abzurufen. Dies ist manchmal problematisch, wenn Sie sich außerhalb der Sitzung faul holen. Zum Beispiel haben Sie eine Ansicht, die die Details eines bestimmten POJOs zeigt.
@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();
}
}
Wenn Sie versuchen, faul außerhalb der Sitzung abgerufen zu werden, erhalten Sie die lazyinitializeException . Dies ist darauf zurückzuführen, dass die Abrufstrategie für alle oneToMany oder andere Beziehungen standardmäßig faul ist (Aufruf der DB bei Bedarf). Wenn Sie die Sitzung geschlossen haben, können Sie nicht mit der Datenbank kommunizieren. Unser Code versucht also, eine Sammlung von gefallenen Seiten abzurufen, und es wird eine Ausnahme ausgelöst, da für das Rendern der Datenbank keine zugeordnete Sitzung vorhanden ist.
Lösung hierfür ist zu verwenden:
- Sitzung in Ansicht öffnen - Hier halten Sie die Sitzung auch in der gerenderten Ansicht offen.
-
Hibernate.initialize(user.getLikedPage())
vor dem Schließen der Sitzung - Dies weist den Hibernate an, die Auflistungselemente zu initialisieren