[ 김영한 스프링 데이터 JPA #6 ] @EntityGraph

김수호·2024년 6월 3일
0
post-thumbnail

실무에서는 대부분 엔티티 연관관계를 설정할 때, 지연로딩을 디폴트로 설정한다.

즉시 로딩으로 적용하게 되면, 만약 설정된 연관관계가 N개인 경우, N개의 테이블이 모두 조인되어 조회되는 등 예상하지 못한 SQL이 발생될 수 있다. 또한 즉시 로딩은 JPQL에서 N+1 문제를 일으킬 수 있다. 여기서 1은 최초 쿼리, N은 최초 쿼리의 결과 개수이다. 즉 최초에 보낸 쿼리 한 번에 해당 결과 개수만큼 추가적으로 쿼리가 발생하는 것이다.

그러면 지연로딩으로 설정하면 모든 문제가 해결될까? 지연로딩으로 설정하더라도 N+1 문제는 발생할 수 있다.

예를 들어, 직원(Employee)부서(Team) 가 다대일 관계, 지연로딩으로 설정되었다고 가정해보자. 그리고 비즈니스 로직에서 직원 목록을 조회하고, 조회된 직원 수 만큼 루프를 돌면서 직원의 부서 정보에 접근( employeeList.getTeam().getName() )한다고 가정해보자. 이때 내부에서는 부서 정보에 접근할 때 마다 DB에 조회 SQL 이 나가게 된다. 즉 조회된 직원의 수 만큼 부서 정보를 조회하기 위한 SQL 이 별도로 나가는 것이다.

따라서, 실무에서는 지연로딩으로 인한 N+1 문제를 해결하기 위해 다음과 같이 페치 조인을 사용한다.

  • ex) select e from Employee e left join fetch e.team
    • Employee 를 조회할 때 연관된 Team 을 같이 한번에 조회한다.

 

🤔 그러면 스프링 데이터 JPA 를 사용할 때도, 페치 조인이 필요한 경우 JPQL 을 직접 작성해야 할까?

스프링 데이터 JPA 에서는 @EntityGraph 를 라는 애노테이션을 통해 편의를 제공한다.

  • ex) @EntityGraph(attributePaths = {"team"})
    • Employee 를 조회할 때 연관된 Team 을 같이 한번에 조회한다. ( JPQL 없이도 객체 그래프를 한 번에 엮어서 조회 )
  • 참고) EntityGraph 정리
    • 사실상 페치 조인(FETCH JOIN)의 간편 버전
    • LEFT OUTER JOIN 사용

강의를 듣고 정리한 글입니다. 코드와 그림 등의 출처는 김영한 강사님께 있습니다.

profile
현실에서 한 발자국

0개의 댓글