hibernate
Leniwe ładowanie kontra chętne ładowanie
Szukaj…
Leniwe ładowanie kontra chętne ładowanie
Pobieranie lub ładowanie danych można przede wszystkim podzielić na dwa typy: chętny i leniwy.
Aby użyć Hibernacji, upewnij się, że dodałeś jego najnowszą wersję do sekcji zależności pliku pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
1. Chętne ładowanie i leniwe ładowanie
Pierwszą rzeczą, o której powinniśmy tutaj porozmawiać, są leniwe ładowanie i chętne ładowanie:
Chętne ładowanie jest wzorcem projektowym, w którym inicjalizacja danych następuje natychmiast. Oznacza to, że kolekcje są pobierane w całości w momencie pobierania ich rodzica (pobieranie natychmiast)
Leniwe ładowanie to wzorzec projektowy, który służy do odroczenia inicjalizacji obiektu do momentu, w którym jest potrzebny. Może to skutecznie przyczynić się do wydajności aplikacji.
2. Korzystanie z różnych rodzajów ładowania
Leniwe ładowanie można włączyć za pomocą następującego parametru XML:
lazy="true"
Przejdźmy do przykładu. Najpierw mamy klasę użytkownika:
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
}
Spójrz na zestaw szczegółów, który mamy. Teraz spójrzmy na klasę OrderDetail :
public class OrderDetail implements Serializable {
private Long orderId;
private Date orderDate;
private String orderDesc;
private User user;
//setters and getters
//equals and hashcode
}
Ważna część, która jest zaangażowana w ustawienie leniwego ładowania w 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>
W ten sposób włącza się leniwe ładowanie. Aby wyłączyć leniwe ładowanie, możemy po prostu użyć: lazy = "false"
a to z kolei umożliwi szybkie ładowanie. Oto przykład konfiguracji szybkiego ładowania w innym pliku 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>
Zakres
Dla tych, którzy nie bawili się tymi dwoma projektami, zakres leniwości i entuzjazmu mieści się w konkretnej sesji SessionFactory . Chętnie ładuje wszystko natychmiast, co oznacza, że nie trzeba dzwonić do niczego, aby je pobrać. Ale opóźnione pobieranie zwykle wymaga pewnych działań w celu odzyskania zmapowanej kolekcji / obiektu. Czasami jest to problematyczne, gdy leniwe pobieranie odbywa się poza sesją . Na przykład masz widok, który pokazuje szczegóły niektórych mapowanych 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();
}
}
Kiedy staramy się leniwy idące poza sesją dostaniesz lazyinitializeException . Wynika to z faktu, że domyślnie strategia pobierania dla wszystkich relacji oneToMany lub innych jest leniwa (połączenie z DB na żądanie), a po zamknięciu sesji nie ma możliwości komunikacji z bazą danych. więc nasz kod próbuje pobrać kolekcję polubionych stron i zgłasza wyjątek, ponieważ nie ma powiązanej sesji do renderowania bazy danych.
Rozwiązaniem tego jest użycie:
- Otwórz sesję w widoku - w której sesja jest otwarta nawet w renderowanym widoku.
-
Hibernate.initialize(user.getLikedPage())
przed zamknięciem sesji - informuje hibernację o zainicjowaniu elementów kolekcji