페치 조인은 SQL에서 이야기하는 조인의 종류는 아니며 JPQL에서 성능 최적화를 위해 제공하는 기능이다.(참고. Lazy 로딩, Eager 로딩, N+1 문제)
이것은 연관된 엔티티나 컬렉션을 한 번에 같이 조회하는 기능이며 JOIN FETCH
명령어로 사용할 수 있다.
select m from Member m join fetch m.team
예제를 보면 join
다음에 fetch
라 적었다. 이렇게 하면 회원 m
과 팀 m.team
이 함께 조회한다. 참고로 일반적인 JPQL 조인과 다르게 m.team
에 별칭이 없는데 JPA의 페치 조인은 별칭을 사용할 수 없다. 다만 하이버네이트는 별칭을 허용한다.
select t from Team t join fetch t.members where t.name = 'teamA'
팀에 회원이 두 명이 있다면 데이터베이스에서 조회되는 데이터는 두 건이다. 그렇게 되면 JPA에서 같은 teamA
를 List<Team>
을 두 개 담게 된다.
이 것을 해결하기 위하여 DISTINCT
키워드를 사용하면 된다.
JPQL은 결과를 반환할 때 연관관계까지 고려하지 않는다. 단지 SELECT
절에 지정한 엔티티만 조회할 뿐이다.
반면에 페치 조인을 사용하면 연관된 엔티티도 함께 조회한다. 그렇기에 지연 로딩이나 즉시 로딩에 비해 SQL 호출 횟수를 줄여 성능을 최적화할 수 있다.
권장하는 페치 전략은 글로벌 로딩 전략을 지연 로딩으로 설정하고 최적화가 필요한 곳에 페치 조인을 사용하는 것이다.
주의할 점은 아래와 같다.
- 페치 조인 대상에는 별칭을 줄 수 없다.
- 둘 이상의 컬렉션을 페치할 수 없다.
- 컬렉션을 페치 조인하면 페이징 API를 사용할 수 없다.
자바 ORM 표준 JPA 프로그래밍 10장