티스토리 뷰

Spring/Hibernate

Hibernate : Lazy and Eager Loading

Korean Eagle 2020. 5. 7. 17:18
728x90

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();
    }
  }
}

 

728x90
댓글