ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA] 즉시로딩 지연로딩 (FetchType)
    JPA 2025. 4. 26. 01:37

    지연로딩

     

    로딩되는 시점에 Lazy 로딩 설정이 되어있는 Team 엔티티는 프록시 객체로 가져온다.

     

    Member findMember = em.find(Member.class, member.getId());
    
    System.out.println(findMember.getTeam().getClass());

     

    Member 조회 시 Team 객체의 클래스를 확인해보면 Proxy 객체가 조회됨.

     

    class hello.jpa.Team$HibernateProxy$e97rdqZR  // 프록시 객체

     

    하지만 팀의 이름을 출력하는 순간에는 실제 Team 엔티티를 참조해야하므로

    추가적인 쿼리가 나간다.

    System.out.println("TEAM NAME : " + findMember.getTeam().getName());

     

    즉 지연로딩은

     

    1. 연관되어있는 객체들은 모두 Proxy 객체들로 가져옴

    2. 연관된 객체를 참조하지 않는 경우에는 N+1 문제를 일으키지 않지만, 지연로딩 후 연관된 객체를 가져올때는 Proxy 객체가 아닌 실제 객체를 조회하기 위한 추가적인 쿼리가 나간다.

     

    결과적으로 EAGER 로딩과 마찬가지로 Team 엔티티를 가져오기 위한 추가 쿼리가 발생해서 N+1 문제가 발생한다!

     

     

    하지만 로그를 잘 살펴보면 재밌는 점이 있습니다.

     

    EAGER 로딩처럼 한번에 추가 쿼리가 3개가 나가는 것이 아니라,

    for문을 돌면서 Member의 닉네임을 출력하는, 즉 Member 엔티티가 사용되는 시점에 추가 쿼리가 발생하여

    추가 쿼리 발생 후 다음 추가 쿼리 발생 전에 출력이 이루어지는 것을 볼 수 있습니다.

     

    이렇게 데이터를 사용하는 시점에 불러오는 것이 LAZY 로딩, 지연 로딩입니다.


    즉시 로딩

     

    즉시로딩은 연관된 객체를 Proxy 객체가 아닌 실제 객체들로 가져오는 경우이다.

     

    하지만 즉시로딩은 다음과 같은 단점이 있다.

     

    1. 연관되어있는 객체를 안쓰는 경우에는 N+1 문제를 야기하므로 쿼리 낭비가 된다.


    즉, 지연로딩과 즉시로딩을 사용할 경우 연관된 데이터를 실제로 사용하는 경우에는 추가적인 쿼리가 나가 모두 N+1 문제를 야기한다!!

     

    따라서 이러한 N+1 문제를 해결하기 위해서

    JPA는 Fetch Join, @EntityGraph와 같은 기능을 지원한다.

     


    따라서 실무에서는 지연로딩을 사용하는 경우도 미미하다!

    보통 대부분 JPQL의 fetch join을 통해서 해당 시점에 한방 쿼리로 가져와서 쓴다.

     

    추가적으로 @EntityGraph, BatchSize 를 설정해서 해결하는 방법이 있다.

    'JPA' 카테고리의 다른 글

    [JPA] Fetch Join  (0) 2025.04.26
    [JPA] 1+N 문제  (1) 2025.04.26
    [JPA] orphanRemoval  (0) 2024.09.10
    [JPA] cascadeType  (0) 2024.09.05
    [JPA] @JoinColumn의 이해  (1) 2024.09.01