스프링 jpa fetch join 페이징 문제 해결

장원재·2024년 4월 5일
1

jpa

목록 보기
3/11

XtoOne (ManyToOne, OneToOne) 관계에 있어서 fetch join 을 사용하면 n + 1 문제가 해결 되는 것을 경험했다. 그런데 fetch join치명적인 단점은 페이징을 못한다는 것이다. 정확하게 말하면 fetch join 을 사용하는 동시에 페이징을 시도하면 하이버네이트는 db에 있는 모든 데이터를 메모리에 가져온 후에 메모리 내에서 페이징을 해버린다. 만약에 db에 데이터가 많은 애플리케이션이라면 out of memoery로 서버가 뻗을 수 있다. 이런 문제를 해결해주는 것이 바로 @BatchSize, hibernate.default_batch_fetch_size 이다.

사용법

# resources/application.yml 에 있는 파일
spring:
  jpa:
    ...
    properties:
      hibernate:
        default_batch_fetch_size: 1000 #최적화 옵션
  • default_batch_fetch_size 를 사용하면 설정한 수만큼 컬렉션이나 프록시 객체를 한번에 가져온다.
  • 쿼리 수는 조금 더 증가하지만 In 쿼리를 사용하므로 DB 데이터 전송량이 감소한다.
  • 가장 좋은 점은 위의 옵션을 사용하면 페이징이 가능해진다.
    public List<Order> findAllWithMemberDelivery(int offset, int limit) {
        return em.createQuery(
                "select o from Order o" +
                        " join fetch o.member m" +
                        " join fetch o.delivery d", Order.class)
                .setFirstResult(offset)
                .setMaxResults(limit)
                .getResultList();
    }
  • default_batch_fetch_size 를 설정해주면 fetch join과 함께 페이징 사용 시 나오는 경고 문구가 사라지게 된다.
profile
데이터 분석에 관심있는 백앤드 개발자 지망생입니다

0개의 댓글

관련 채용 정보