0. 개요
- 이번 포스팅에서는 Fetch Join의 한계에 대해서 알아보자.
1. Fetch Join의 한계
- Fetch Join 사용 시, 하지 못하는 것 또는 하면 안 되는 것에 대해서 알아보자.
a) 별칭, Where 절 사용 금지
- Fetch Join을 사용할 때에는 별칭과 Where 절을 사용하지 않는 것을 권장한다.
- 첫 번째 이유는 Fetch Join의 역할 또는 정의를 위배하기 때문이다.
- Fetch Join은 연관된 Entity를 모두 조회한다는 정의를 가지고 있다.
- 그러나 Where 절을 통한 필터링은 Fetch Join의 결과 값에 변화를 주게 된다.
- 즉, 연관된 Entity를 모두 조회한다는 역할이 필터링을 사용함으로써 변질되는 것이다.
- 두 번째 이유는 데이터 무결성을 위배하기 때문이다.
- DB의 측면에서 Fetch Join의 결과가 3개라면 JPA에서도 3개의 데이터를 사용해야 한다.
- 그러나 Where 절을 통해 필터링된 데이터가 1개라면 JPA에서는 Fetch Join의 결과로 1개의 데이터를 사용한다.
- 즉, DB와 JPA의 데이터 싱크가 맞지 않게 되므로 데이터 무결성이 위배된다.
- 예외적으로, 재귀적인(= 연속적인) Fetch Join을 사용하기 위한 경우 별칭의 사용을 허가한다.
- 재귀적인 Fetch Join은 데이터 무결성 또는 Fetch Join의 정의를 위배하지 않기 때문이다.
- 결론으로, Fetch Join과 Where 절을 함께 사용하지 말고 일반적인 Join을 사용하면 된다.
b) 둘 이상의 컬렉션은 Fetch Join 할 수 없다.
- 상황에 따라 다르지만 두 컬렉션의 Fetch Join은 컬렉션 * 컬렉션의 결과를 만든다.
- 즉, 카테시안 곱의 결과를 만들어낸다. (조회 데이터가 엄청나게 증가한다.)
- Hibernate 사용 시, 둘 이상의 컬렉션을 사용한 Fetch Join은 오류를 발생시킨다.
- 그러므로 사용하지 말자.
c) Collection Fetch Join은 페이징을 사용할 수 없다.
- 일대일(OneToOne), 다대일(ManyToOne)의 경우 Fetch Join과 페이징을 사용할 수 있다.
- 그 이유는 데이터가 컬렉션 Fetch Join과 다르게 데이터가 증가하지 않기 때문이다.
- 즉, 조회된 데이터의 수를 예상할 수 있다.
- 그러나 컬렉션 Fetch Join의 경우, 페이징을 사용할 수 없다.
- 그 이유는 데이터의 수를 가늠하기가 힘들다.
- 그러므로 잘못된 페이지 사이즈를 설정이 데이터 누락을 초래하게 된다.
- Hibernate에서는 Fetch Join과 페이징을 사용할 수 있다.
- 다만, 경고가 발생한다.
- 굳이 컬렉션을 사용한 Fetch Join을 사용해야 한다면, 반대로 쿼리를 작성하면 된다.
- 즉, OneToMany를 ManyToOne으로 접근할 수 있도록 쿼리를 작성하는 것이다.
2. 결론
- Fetch Join은 JPQL의 성능 최적화를 위하여 사용한다.
- 그러므로 N + 1 케이스가 발생하는 부분을 해결하기 위해서 사용한다.
- 즉, 최적화가 필요한 곳에서 Fetch Join을 사용하자.
'Back-end > JPA 개념' 카테고리의 다른 글
35. JPQL - 벌크 연산 (0) | 2022.05.08 |
---|---|
34. JPQL - 다형성 쿼리, Entity 직접 사용, Named 쿼리 (0) | 2022.05.07 |
32. JPQL - Collection Fetch Join과 Distinct (0) | 2022.05.05 |
31. JPQL - Fetch Join 개념 (0) | 2022.05.04 |
30. JPQL - 경로 표현식과 묵시적 JOIN (0) | 2022.05.03 |
댓글