hibernate
Lazy Loading vs Ivrig Loading
Sök…
Lazy Loading vs Ivrig Loading
Hämta eller ladda data kan primärt klassificeras i två typer: ivriga och lata.
För att använda Viloläge, se till att du lägger till den senaste versionen av den till beroendeavsnittet i din pom.xml-fil:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
1. Ivrig lastning och lat laddning
Det första vi bör diskutera här är vad lat laddning och ivrig lastning är:
Eager Loading är ett designmönster där datainitialisering sker på plats. Det betyder att samlingar hämtas helt när deras förälder hämtas (hämta omedelbart)
Lazy Loading är ett designmönster som används för att skjuta upp initialisering av ett objekt till den punkt där det behövs. Detta kan effektivt bidra till applikationens prestanda.
2. Använda olika typer av lastning
Lat laddning kan aktiveras med hjälp av följande XML-parameter:
lazy="true"
Låt oss undersöka exemplet. Först har vi en användarklass:
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
}
Titta på den uppsättning beställningsdetaljer som vi har. Låt oss nu titta på OrderDetail-klassen :
public class OrderDetail implements Serializable {
private Long orderId;
private Date orderDate;
private String orderDesc;
private User user;
//setters and getters
//equals and hashcode
}
Den viktiga delen som är involverad i att ställa in den lata laddningen i 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>
Så här är den lata lastningen aktiverad. För att inaktivera lat laddning kan vi helt enkelt använda: lazy = "false"
och detta i sin tur möjliggör ivrig lastning. Följande är exempel på inställning av ivrig laddning i en annan fil 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>
Omfattning
För dem som inte har spelat med dessa två mönster ligger omfattningen av lata och ivriga inom en specifik Session of SessionFactory . Ivrig laddar allt direkt, betyder att det inte finns något behov att ringa något för att hämta det. Men lat hämtning kräver vanligtvis en del åtgärder för att hämta mappad samling / objekt. Ibland är det problematiskt att få lata hämtningar utanför sessionen . Till exempel har du en vy som visar detaljerna i en del mappade POJO.
@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();
}
}
När du försöker få lata hämtad utanför sessionen får du lazyinitializeException . Detta beror på att hämtningsstrategi som standard för alla oneToMany eller någon annan relation är lat (ring till DB på begäran) och när du har avslutat sessionen har du ingen makt att kommunicera med databasen. så vår kod försöker hämta samling av likesPage och den kastar undantag eftersom det inte finns någon tillhörande session för rendering av DB.
Lösning för detta är att använda:
- Öppna session i vy - där du håller sessionen öppen även i den visade vyn.
-
Hibernate.initialize(user.getLikedPage())
innan stängningssession - Detta berättar för viloläge att initiera samlingselementen