MultipleBagFetchException(두개의 Fetch Join)

2024. 10. 8. 13:40·Java & Spring/트러블슈팅

- 문제상황

        List<Todo> results = jpaQueryFactory
                .selectFrom(todo)
                .leftJoin(todo.managers).fetchJoin()
                .leftJoin(todo.comments).fetchJoin()
                .where(condition)
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();
  • todo조회 시 manager와 comment의 개수를 출력하면서 N+1문제를 해결하기 위해 Fetch Join을 연속으로 두개 사용
  • MultipleBagFetchException 발생
    -> 2개 이상의 OneToMany 자식 테이블에 Fetch Join을 선언했을때 발생
    MultipleBagFetchException의 원인
    Hibernate는 여러 개의 List 타입 @OneToMany 또는 @ManyToMany 관계를 Fetch Join으로 동시에 로딩할 때, 내부적으로 "중복된 레코드"를 제거하는 방식 때문에 발생, List는 순서를 보장해야 하기 때문에, 데이터베이스에서 조회된 결과를 그대로 유지해야 하며, 중복 제거 시 복잡성이 증가 이로 인해, Hibernate는 여러 컬렉션을 List로 Fetch Join하는 경우 예외를 던지게됨.

 

- 해결방법

 

1. 객체수가 많은 comment는 fetchjoin으로 대비 작은 manager은 BatchSize로 해결

   List<Todo> results = jpaQueryFactory
                .selectFrom(todo)
                .leftJoin(todo.managers)
                .leftJoin(todo.comments).fetchJoin()
                .where(condition)
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();
           
    // Todo Entity
    public class Todo extends Timestamped {             
        @OneToMany(mappedBy = "todo", cascade = CascadeType.PERSIST)
        @BatchSize(size = 10)
        private List<Manager> managers = new ArrayList<>();
    }

 

2. OneToMany부분을 Set으로 받아 처리

    @OneToMany(mappedBy = "todo", cascade = CascadeType.REMOVE)
    private Set<Comment> comments = new HashSet<>();

    @OneToMany(mappedBy = "todo", cascade = CascadeType.PERSIST)
    private Set<Manager> managers = new HashSet<>();

'Java & Spring > 트러블슈팅' 카테고리의 다른 글

@Transactional(propagation = Propagation.REQUIRES_NEW)  (0) 2024.10.10
Self-invocation(자기 호출)  (0) 2024.09.05
'Java & Spring/트러블슈팅' 카테고리의 다른 글
  • @Transactional(propagation = Propagation.REQUIRES_NEW)
  • Self-invocation(자기 호출)
DJ.Kang
DJ.Kang
백엔드 개발 기록 블로그
  • DJ.Kang
    DJ Hello World
    DJ.Kang
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 이론공부
      • 시스템설계
      • Java & Spring
        • TIL
        • 트러블슈팅
        • 고도화
        • 알고리즘
        • 코딩테스트
        • Java
        • Spring
        • Thymeleaf
      • 프로젝트
        • coin-trading
        • 트러블슈팅
      • Docker
      • DB
      • AWS
      • CI-CD
      • 웹
      • git & github
      • 구인공고분석
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    java 에라토스테네스의 체
    데이터 타입
    자료구조
    java 메서드
    데이터 크기
    java
    java super
    java 유클리드 호제법
    개발로드맵
    java 세수의합
    프로그래머스 java 기초트레이닝
    java 제어자
    java기초
    Java 생성자
    java arrays.copyofrnage()
    프로그래머스 java 기초 트레이닝
    java two-pointer
    java 멤버
    java enhance switch
    Java this
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
DJ.Kang
MultipleBagFetchException(두개의 Fetch Join)
상단으로

티스토리툴바