수색…


게으른 로딩 대 열렬한 로딩

데이터를 가져 오거나로드하는 것은 크게 두 가지 유형으로 구분할 수 있습니다.

Hibernate를 사용하기 위해서는 pom.xml 파일의 dependencies 섹션에 최신 버전을 추가해야한다.

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>   
    <version>5.2.1.Final</version>
</dependency>

1. 열렬한 적재 및 적재 적재 적재

우리가 여기서 논의해야 할 첫 번째 일은 게으른 로딩과 열망하는 로딩이 무엇인지입니다 :

Eager Loading은 데이터 초기화가 그 자리에서 일어나는 디자인 패턴입니다. 이는 부모가 가져온 시점에 컬렉션을 완전히 가져 오는 것을 의미합니다 (즉시 가져 오기).

Lazy Loading은 객체가 필요한 시점까지 객체 초기화를 지연시키는 데 사용되는 디자인 패턴입니다. 이는 응용 프로그램의 성능에 효과적으로 기여할 수 있습니다.

2. 다양한 유형의 로딩 사용하기

Lazy 로딩은 다음 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
    }

우리가 가지고있는 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 에서 지연로드 설정과 관련된 중요한 부분은 다음과 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에서 eager loading을 설정하는 예제입니다.

<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>

범위

이 두 가지 디자인으로 연주하지 않은 사람들을 위해, 게으르고 열망하는 범위는 특정 Session of SessionFactory 내에 있습니다. Eager는 모든 것을 즉시로드합니다. 즉, 가져 오는 데 아무 것도 호출 할 필요가 없습니다. 그러나 게으른 가져 오기는 일반적으로 매핑 된 컬렉션 / 개체를 검색하기위한 몇 가지 작업을 요구합니다. 이것은 때때로 세션 밖에서 게으른 가져 오기를 얻는 데 문제가 있습니다. 예를 들어 매핑 된 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 또는 다른 릴레이션에 대한 페치 전략이 지연 (요청시 DB 호출)하고 세션을 닫을 때 데이터베이스와 통신 할 권한이 없기 때문입니다. 그래서 우리 코드는 favoritePage의 콜렉션을 가져 오려고 시도하고 DB 렌더링을위한 관련 세션이 없기 때문에 예외를 던집니다.

이를위한 해결책은 다음과 같습니다.

  1. 보기에서 열린 세션 - 렌더링 된보기에서도 세션을 열어 두는 곳입니다.
  2. 세션을 닫기 전에 Hibernate.initialize(user.getLikedPage()) - 이것은 hibernate에게 콜렉션 요소를 초기화하도록 지시한다.


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow