컬레션 페치 조인이란
"1 대 n " 에서 1 에 해당하는 엔티티와 n 에 해당하는 엔티티와 fetch join 을 하는것이다.
하지만 여기서 문제점은 '다' 에 해당하는 컬렉션과 페치조인을 하면 데이터가 뻥튀기 된다는 문제점이다. 실제 테이블에서 일어나는 일이다.
TeamA -> member1, member2, member3
TeamB -> member4, member5, member 6
가 있다고 가졍했을대 조인을 했을경우 데이터가 많은 member 쪽에 맞춰서 TeamA 가 3개
TeamB가 세개가 될것이다.
(직접 그려서 확인해봐)
하지마 JPA 에서 하이버네이스 6기준 이후로는 이 뻥튀기 된 데이터를 "어플리케이션"단에서
List 에 중복이 있을경우 중복을 알아서 제거해준다.
@Test
public void findMemberLazy3() {
//given
//member1 -> teamA
//member2 -> teamB
Team teamA = new Team("teamA");
Team teamB = new Team("teamB");
teamRepository.save(teamA);
teamRepository.save(teamB);
Member member1 = new Member("member1", 10, teamA);
Member member2 = new Member("member2", 10, teamA);
Member member3 = new Member("member3", 10, teamA);
Member member4 = new Member("member4", 10, teamA);
Member member5 = new Member("member5", 10, teamB);
Member member6 = new Member("member6", 10, teamB);
Member member7 = new Member("member7", 10, teamB);
memberRepository.save(member1);
memberRepository.save(member2);
memberRepository.save(member3);
memberRepository.save(member4);
memberRepository.save(member5);
memberRepository.save(member6);
memberRepository.save(member7);
em.flush();
em.clear();
List<Team> result = em.createQuery("select t from Team t join fetch t.members m", Team.class)
.getResultList();
System.out.println(result.size());
result.forEach(
team -> {
System.out.println("====== teamName " + team + "=====");
team.getMembers().forEach(System.out::println);
}
);
}
원래는 데이터가 뻥튀기 되니깐 List<Member> 에는 뻥튀긴 데이터 즉 같은 Team 이 많이 나올 것으로 예상이 되었지만 TeamA , TeamB 이렇게 결과가 나왔다.

이 처럼 어플리케이션 단에서 (java) 에서 일어나는 일이다.
여기서 중요한게 실제 fetch join 을 컬렉션과 했을경우 페이징을 할수 없다는것이다!!
왜냐하면
중복 row 기준으로 LIMIT/OFFSET이 적용됨 → 원하는 만큼의 "Team"이 안 나올 수 있음

그리고 나머지 컬렉션은 LAZY 로 하고 BATCH SIZE 를 조정해서 1 + n 문제를 해결하자.