fetch join 적용 (fetch type 은 상관 없음)
발생 쿼리 로그
출력 로그
페치 조인을 통해 단 한방의 join 쿼리가 발생하고 결과 엔티티의 연관관계를 jpa 가 마법처럼 매핑 해 주었습니다.
만약 여기서 fetch 키워드를 jpql에서 제거하면 같은 쿼리가 발생합니다.
하지만 jpa는 이를 채워야 할 근거가 없기 때문에 얻어온 t.teamname 과 같은 team의 필드를 그냥 버립니다.
이후에 연관관계의 fetch 옵션 (EAGER/LAZY)에 따라 추가 적인 쿼리를 발생 시킵니다.
컬렉션 페치 조인
팀을 조회 하며 소속된 멤버를 모두 조회하는 @OneToMany의 관계에서의 fetch join도 확인해 보겠습니다.
한방 쿼리가 발생하였고 팀 데이터의 컬렉션 연관관계인 users field에 대해 매핑을 잘 해주었습니다.
하지만 데이터를 살펴 보면 뻥튀기가 발생한 것을 알 수 있습니다.
뻥튀기가 발생한 이유는 db 쿼리의 실행결과를 생각해보면 금방 이해할 수 있습니다.
쿼리 실행 결과
t.id | u.id | t.teamname | u.team_id | u.username |
1 | 1 | 해바라기반 | 1 | 짱구 |
1 | 2 | 해바라기반 | 1 | 유리 |
2 | 3 | 장미반 | 2 | 치타 |
3 | 4 | 어린이 탐정단 | 3 | 코난 |
이 데이터를 그대로 result set에 담아서 풀기 때문에 jpa 레벨에서는 team 데이터의 뻥튀기가 발생할 수 밖에 없습니다. @NtoMany관계의 어쩔 수 없는 숙명입니다.
하이버네이트는 이를 위한 jpql 키워드 distinct를 제공합니다.
distinct 키워드는 두가지 역할을 합니다.- 쿼리에 distinct 키워드 (sql의 distinct)
- 어플리케이션 레벨에서 중복 데이터의 제거 (주소 기반)