Fetch Join은 JPQL에서 연관된 엔티티나 컬렉션을 한 번의 SQL로 함께 조회하기 위한 기능입니다. join fetch 구문을 사용하며, 조회한 연관관계를 영속성 컨텍스트에 함께 적재하고 로딩이 완료된 상태로 만듭니다.

select distinct t
from Team t
join fetch t.members

일반 Join은 조인한 대상을 조건이나 정렬에 활용하는 것이 주목적이며, 조회 대상에 명시하지 않은 연관관계까지 초기화해 주지는 않습니다. 따라서 SQL에 JOIN이 있더라도 이후 연관관계에 접근할 때 추가 쿼리가 실행될 수 있습니다. 반면 Fetch Join은 연관 엔티티를 함께 조회하는 것이 목적이므로 N+1 문제를 해결할 때 자주 사용합니다.

다만 일대다 컬렉션을 Fetch Join하면 SQL 결과에서 부모 행이 자식 수만큼 중복될 수 있습니다. JPQL의 distinct로 결과 목록의 부모 엔티티 중복을 제거할 수 있지만, 컬렉션 Fetch Join과 페이징을 함께 사용하거나 여러 컬렉션을 동시에 Fetch Join하는 것은 데이터 증가와 예외 가능성 때문에 주의해야 합니다.