hibernate
Лётная загрузка против желаемой загрузки
Поиск…
Лётная загрузка против желаемой загрузки
Извлечение или загрузка данных можно в первую очередь классифицировать на два типа: нетерпеливые и ленивые.
Чтобы использовать Hibernate, обязательно добавьте последнюю версию этого файла в раздел зависимостей вашего файла pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
1. Желание загрузки и ленивой загрузки
Первое, что мы должны обсудить здесь, - это то, что ленивая загрузка и интенсивная загрузка:
Eager Loading - это шаблон проектирования, в котором происходит инициализация данных на месте. Это означает, что коллекции извлекаются полностью во время получения родительских прав (выборка сразу)
Lazy Loading - это шаблон дизайна, который используется для отсрочки инициализации объекта до точки, в которой он необходим. Это может эффективно влиять на производительность приложения.
2. Использование разных типов загрузки
Ленивую загрузку можно включить с помощью следующего параметра XML:
lazy="true"
Давайте рассмотрим пример. Сначала у нас есть класс User:
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
}
Посмотрите на Set of OrderDetail, который у нас есть. Теперь давайте посмотрим на класс OrderDetail :
public class OrderDetail implements Serializable {
private Long orderId;
private Date orderDate;
private String orderDesc;
private User user;
//setters and getters
//equals and hashcode
}
Важная часть, которая связана с установкой ленивой загрузки в 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>
Так разрешена ленивая загрузка. Чтобы отключить ленивую загрузку, мы можем просто использовать: lazy = "false"
и это, в свою очередь, позволит загружать с нетерпением. Ниже приведен пример настройки активной загрузки в другом файле 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>
Объем
Для тех, кто не играл с этими двумя проектами, объем ленивых и нетерпеливых находится на определенной сессии SessionFactory . Легко загружает все мгновенно, означает, что нет необходимости называть что-либо для его получения. Но ленивый выбор обычно требует некоторых действий для извлечения сопоставленной коллекции / объекта. Иногда это проблематично, когда вы получаете ленивую выборку за пределами сеанса . Например, у вас есть представление, которое показывает детали некоторого отображаемого 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();
}
}
Когда вы попытаетесь получить ленивый выбор вне сеанса, вы получите lazyinitializeException . Это связано с тем, что по умолчанию стратегия выборки для всего oneToMany или любого другого отношения является ленивым (вызов по требованию по требованию), а когда вы закрыли сеанс, у вас нет возможности связываться с базой данных. поэтому наш код пытается получить подборку понравившегося файла и он выдает исключение, потому что не существует связанного сеанса для рендеринга БД.
Решением для этого является использование:
- Открыть сеанс в представлении - в котором вы держите сессию открытой даже на визуализированном представлении.
-
Hibernate.initialize(user.getLikedPage())
перед закрытием сессии. Это говорит о спящем режиме для инициализации элементов коллекции