MultipleBagFetchException

조현근·2022년 11월 12일
0
post-thumbnail

N+1 학습테스트를 진행하다 'MultipleBagFetchException'를 마주쳤다.
어떤 예외인지 공부해보자.

MultipleBagFetchException

공식문서에 따르면 동시에 다수의 'Bag'을 fetch하려 했을때 발생하는 예외라 한다.

아래와 같은 엔티티를 작성하면 'MultipleBagFetchException'을 마주칠 수 있다.

왜 발생할까?

두개 혹은 그 이상의 'Bag'을 fetch하면 'Cartesian product'가 일어난다고 한다.
hibernate에서 Cartesian Product 문제가 발생하는 경우를 알아보자.

Member엔티티에서 Post와 Comment를 모두 @OneToMany(Eager)로 관계를 맺고 있다.
(둘 다 List를 사용하면 'MultipleBagFetchException'이 발생한다. 그래서 Comment는 Set 자료구조를 사용했다.)

아래 테스트코드를 실행하면 left outer join이 두 번 중첩된 쿼리가 나가는걸 확인할 수 있다.

'Bag'을 이용했을때 어떤 문제가 발생하기에 hibernate에선 두 개 이상의 'Bag'을 fetch하려하면 'MultipleBagFetchException'을 발생시킬까?
직접 MySQL에 데이터를 넣고 위 쿼리의 결과 테이블이 어떻게 나오는지 확인해보았다.
가장 극한의 상황을 가정하기 위해 Post와 Comment에 모두 중복되는 데이터를 넣어주었다.
그리고 아래 쿼리를 실행시켜 결과를 확인했다.

식별자를 의미하는 column을 제외하면 사실상 모든 데이터가 동일한 것을 알 수 있다. 'Bag'은 중복데이터를 허용하기 때문에 2개 이상의 'Bag'을 fetch하면 쓸모없는 중복 데이터가 많이 생성되기에 hibernate에서 예외를 던지도록 설정한 것 같다.

https://www.baeldung.com/java-hibernate-multiplebagfetchexception
https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/loader/MultipleBagFetchException.html
https://perfectacle.github.io/2019/05/01/hibernate-multiple-bag-fetch-exception/
https://allaroundjava.com/hibernate-cartesian-product-problem/

profile
안녕하세요!

0개의 댓글