Поиск…


Лётная загрузка против желаемой загрузки

Извлечение или загрузка данных можно в первую очередь классифицировать на два типа: нетерпеливые и ленивые.

Чтобы использовать 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 или любого другого отношения является ленивым (вызов по требованию по требованию), а когда вы закрыли сеанс, у вас нет возможности связываться с базой данных. поэтому наш код пытается получить подборку понравившегося файла и он выдает исключение, потому что не существует связанного сеанса для рендеринга БД.

Решением для этого является использование:

  1. Открыть сеанс в представлении - в котором вы держите сессию открытой даже на визуализированном представлении.
  2. Hibernate.initialize(user.getLikedPage()) перед закрытием сессии. Это говорит о спящем режиме для инициализации элементов коллекции


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow