@EntityGraph
와 fetch join
의 차이를 처음에는 어노테이션으로 손쉽게 fetch join
을 작성하는 방법즉, 둘다 같은 쿼리를 날리는것 아닌가? 라는 생각을 하였다. 하지만 실제 쿼리결과도 다를뿐더러 @EntityGraph
와 fetch join
은 개념적으로 차이가 있다.
1. @EntityGraph는 LEFT OUTER JOIN, FETCH JOIN은 INNER JOIN
- 조인 방식부터 다르다.
- @EntityGraph 쓰면 LEFT OUTER JOIN으로 실행된다.
- FETCH JOIN은 기본적으로 INNER JOIN이다.
- 물론 FETCH JOIN도 LEFT JOIN FETCH로 쓰면 OUTER JOIN 가능하다.
2. FetchType을 런타임에 동적 변경 가능
- 엔티티 필드의 fetchType.Lazy랑 fetchType.Eager는 static 정보라 런타임에 못 바꾼다.
- 근데 @EntityGraph는 이걸 동적으로 바꿀 수 있다.
- 예를 들어, @EntityGraph 옵션으로 쿼리 메서드 실행 시 모든 연관 엔티티를 Lazy로 로드하거나, 엔티티에 설정된 FetchType대로 로드하게 설정할 수 있다.
3. 쿼리 작성 방식의 유연성 차이
- FETCH JOIN은 JPQL에 직접 조인 조건을 명시해야 한다. 예: JOIN FETCH p.placeImages.
- @EntityGraph는 쿼리 없이 어노테이션으로 로드할 속성만 정의하면 된다.
- @EntityGraph가 코드가 단순해지고 유지보수 쉬워진다.
4. 다중 컬렉션 처리의 차이 (없음)
FETCH JOIN은 두 개 이상 컬렉션 로드하려면 MultipleBagFetchException 터진다.
@EntityGraph는 다중 컬렉션 로드 가능하지만, 카테시안 곱 발생할 수 있다.
단건 조회든 다건 조회든 @EntityGraph도 다중 컬렉션 많으면 주의해야 한다.
- @EntityGraph 도 내부적으로 fetch join을 사용하기 때문에 2개 이상의 bag(list) 타입 컬렉션을 동시에 fetch 하면 MultipleBagFetchException 이 발생한다.