반응형
N+1 문제를 해결하기 위해 Fetch join을 사용하다 보면 한 엔티티에서 여러 리스트를 Fetch join하는 경우가 있다. 이때 MultipleBagFetchException이 발생할 수 있다. (Bag은 JPA에서 만들어둔 중복을 허용하고 순서가 없는 컬렉션이고, 영속성 컨텍스트에 등록할 때 List를 Bag으로 포장한다고 생각하자)
아무튼 실제 SQL에서는 여러 테이블을 Fetch join하는 쿼리를 작성할 수 있는데 JPA는 왜 예외를 던질까? 간단히 말하자면 쿼리 성능에 악영향을 끼치는 카테시안 곱이 발생했음을 경고하기 위해서다. 친절한 JPA ㅋㅋㅋ..
대응 방법
여러가지 방법이 있겠지만 공부한 내용만 나열한다.
- 하나의 컬렉션만 Fetch Join하기: 한 쿼리에서 여러 컬렉션을 FETCH JOIN하는 대신, 필요한 컬렉션 하나만 FETCH JOIN하고 나머지는 따로 조회하자. 이 방법은 세 엔티티가 1:N-1:N 관계로 이루어지지 않았다면 카테시안 곱을 회피할 수 있다. 하지만 위와 같은 경우라면 배치 사이즈 설정으로 최적화 하는 방법을 고려해야 한다.
- 배치 사이즈 설정: Hibernate의 @BatchSize 어노테이션을 사용하여 지연 로딩 시 가져오는 컬렉션의 사이즈를 조절할 수 있다.
- Bag 말고 Set 사용하기: 예외를 발생시키진 않지만 카테시안 곱은 여전히 발생하므로 예외를 회피하려는 수단 정도로만 생각하자.
반응형
'Tool > Java' 카테고리의 다른 글
[Spring] JPA 복합 키 사용하기 (0) | 2023.12.20 |
---|---|
[Java] 리플렉션 API 간단 정리 (0) | 2023.10.23 |
[Java] CUI 키오스크 (내일배움캠프 과제) (0) | 2023.10.20 |
[Java] Stream API 기초 정리 (0) | 2022.12.09 |