hibernate
게으른 로딩 대 열렬한 로딩
수색…
게으른 로딩 대 열렬한 로딩
데이터를 가져 오거나로드하는 것은 크게 두 가지 유형으로 구분할 수 있습니다.
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 렌더링을위한 관련 세션이 없기 때문에 예외를 던집니다.
이를위한 해결책은 다음과 같습니다.
- 보기에서 열린 세션 - 렌더링 된보기에서도 세션을 열어 두는 곳입니다.
- 세션을 닫기 전에
Hibernate.initialize(user.getLikedPage())
- 이것은 hibernate에게 콜렉션 요소를 초기화하도록 지시한다.