Hibernate : Lazy and Eager Loading
1. 하이버네이트의 FetchType은 어떤 Entity를 데이터베이스에서 가져올 때
2. 관계를 가지는 다른 Entity의 정보를 언제 로딩하는 지에 대한 설정이다.
2-1 Eagar은 Entity의 데이터를 가지고 오면서 같이 관계가 있는 Entity의 정보까지 같이 가지고 온다.
2-2 Lazy는 나중에 필요시에 관계 Entity의 정보를 가지고 온다.
3. 하이버네이트의 기본 FetchtType은 각 Mapping마다 다른데
3-1 @OneToOne은 Eager
3-2 @OneToMany는 Lazy
3-3 @ManyToOne은 Eager
3-4 @ManyToMany는 Lazy
3-5 Default 설정은 일관적인 부분이 있는데 관계를 맺는 상태 entity가 one side이면 Eager many side면 Lazy가 된다.
3-5-1 이것은 당연하게도 하나의 데이터를 가지고 오는 건 부담이 없지만 많은 데이터를 가지고 올 경우 부담이 된다.
3-6 기본값이 아주 상식적이라서 실제 작업시 별도설정의 필요를 못느낀다.
4. Lazy Loading에서 관계있는 데이터를 가지고 오는 방법
4-1 기본적으로 Session이 close되지 않은 상태에서만 가능하다.
4-2 session.get 메소드를 통해 목적하는 entity데이터를 가져오고 가져온 후
4-2-1 entity의 getter 호출하여 관계 데이터를 가져온다.
4-3 HQL을 사용해서 한번에 데이터를 다 가져온다.
4-3-1 이 경우는 데이터를 Eagar loading처럼 데이터를 이미 다 가져오기 때문에
4-3-2 session close되어도 가져온 데이터를 사용할 수 있다.
4-3-3 간단한 예제는 다음과 같다. 데이터베이스는 이전 포스트와 동일하다.
public class FetchEntityWithHQL {
public static void main(String[] args) {
SessionFactory factory = new Configuration().configure()
.addAnnotatedClass(Instructor.class)
.addAnnotatedClass(InstructorDetail.class)
.addAnnotatedClass(Course.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try {
session.beginTransaction();
String queryString = "from Instructor i join fetch i.courses where i.id= :instructorId";
Query<Instructor> query = session.createQuery(queryString, Instructor.class);
query.setParameter("instructorId", 4L);
Instructor instructor = query.getSingleResult();
session.getTransaction().commit();
instructor.getCourses().stream().forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
factory.close();
}
}
}