일반 Join은 단순히 연관된 엔티티를 조인해 조건을 걸거나 필터링할 때 사용한다. 연관된 엔티티의 데이터를 가져오는 것이 아니다.
조회된 결과는 기본 엔티티만 영속성 컨텍스트에 저장되고 연관된 엔티티는 지연 로딩으로 필요할 때 추가 쿼리가 실행된다.
select m from Member m join m.team t where t.name = '개발팀';
이렇게 쿼리를 날리면 member만 영속성 컨텍스트에 저장되고 team은 아직 로딩되지 않기에, 추후에 다시 쿼리를 날려야 한다.
Fetch Join은 연관된 엔티티를 함께 조회하기 위한 JPA 전용 문법이다. 이때 한 번의 쿼리로 연관된 엔티티까지 모두 로딩하기에 N+1 문제를 해결하는데 효과적이다.
select m from Member m join fetch m.team;
이렇게 member 테이블에 쿼리를 날리면 member, team 모두 영속성 컨텍스트에 저장된다.
| 구분 | 일반 조인 (Join) | 패치 조인 (Fetch Join) |
|---|---|---|
| 목적 | 조건 필터링, 연관 데이터 기준 검색 | 연관 엔티티를 즉시 함께 로딩 |
| 로딩 방식 | 지연 로딩 (필요 시 추가 쿼리 발생) | 즉시 로딩 (한 번의 쿼리로 해결) |
| SQL 실행 횟수 | 여러 번 발생 가능 (N+1 문제) | 한 번의 쿼리 |
| 사용 위치 | where, select 등 다양한 조건 | select절에만 사용 가능 |
| 영속성 컨텍스트 반영 | 기본 엔티티만 저장 | 연관 엔티티까지 함께 저장 |