- 페치 조인 대상에는 별칭을 줄 수 없다.
=====================================================================
"select t from Team t join fetch t.member as m"
=====================================================================
※ 하이버네이트는 가능, 가급적 사용하면 안됨
※ 페치조인은 연관된 데이터를 다 긁어옴
※ 객체 그래프는 데이터를 전부다 조회해야함
※ Team을 조회해서 Member에 대한 조건을 날리고 싶으면 처음부터 Member를 조회하는게 맞음
※ 옵션에 따라서 데이터가 지워질 수도 있음
※ 유일하게 사용하는 경우는 join fetch 를 여러개 사용할 때 사용함
- 둘 이상의 컬렉션은 페치 조인 할 수 없다.
1:N도 데이터가 뻥튀기가 되는데 1:N:N여서 데이터가 예상할수 없을 만큼 늘어 날 수 있음.
- 컬렉션을 페치 조인하면 페이징API (setFirstResult, setMaxResults)를 사용할 수 없다.
- 일대일, 다대일 같은 단일 값 연관 필드들은 페치 조인해도 페이징 가능
- 하이버네이트는 경고 로그를 남기고 메모리에서 페이징(매우 위험)
DB에서 모든 데이터를 긁어 온 뒤 메모리에서 작업함..
아래의 쿼리에 페이징이 필요할 경우
=====================================================================
"select t from Team t join fetch t.member as m"
=====================================================================
아래와 같이 뒤집어서 사용
=====================================================================
"select m From Member m join fetch m.team t"
=====================================================================
또는 아래와 같이 쿼리를 작성하고 setFristResult , setMaxResult를 지정
=====================================================================
"select t from Team t"
=====================================================================
위와같이 작성하고 페이징 api를 사용하면 가능한대 성능이 좋지 않음
그래서 위와 같을 때 해당 필드에 @BatchSize(size =100) 옵션을 줌
- @BatchSize 옵션은 Team 을 가져올 때 laze 로딩으로 불러 올때 연관된 데이터를 지정한 사이즈 만큼 불러옴
사이즈는 1000 이하로 사용
또한 해당 옵션은 글로벌 세팅으로 지정해줄 수 있음
hibernate.default_batch_fetch_size , value = 100
- DTO로 쿼리 직접 작성해서 사용
※ JPA의 70~80% 성능 문제는 fetch join 으로 해결됨
- 연관된 엔티티들을 SQL 한번으로 조회 - 성능 최적화
- 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선함
@OneToMany(fetch = FetchType.LAZY) //글로벌 로딩 전략
- 실무에서 글로벌 로딩 전략은 모두 지연 로딩
- 최적화가 필요한 곳은 페치 조인 적용
- 모든 것을 페치 조인으로 해결할 수 는 없음
- 페치 조인은 객체 그래프를 유지할 때 사용하면 효과적
- 여러 테이블을 조인해서 엔티티가 가진 모양이 아닌 전혀 다른 결과를 내야 하면,
페치 조인보다는 일반 조인을 사용하고 필요한 데이터들만 조회해서 DTO로 반환하는 것이 효과적
※ 해결방안 세가지
- 엔티티를 페치조인으로 조회해온다
- 페치조인 한 뒤 어플리케이션에서 DTO로 바꿔서 짠다
- 처음부터 DTO로 짠다