Blog

트러블 슈팅 : JPA 페이징 처리

tag
기능 구현
날짜
2023/10/21
생성 일시
2023/10/28 06:39
작성자

문제 상황

1.
JPA 페이징 처리 문제BookDonationEventBook 간의 1대다 관계에서 BookDonationEvent 중심의 페이징 쿼리 실행 시 원하는 결과를 얻지 못하는 현상이 발생했다. 커스텀 커리를 작성하였지만 정상적으로 동작하지 않는다. 도서와 event가 1대 다 관계라서 정상적으로 작동하지 않는 걸로 추정된다.
@GetMapping("{donationId}") public String bookApplyDonationEventPage(Model model, @PathVariable Long donationId) { BookDonationEvent bookDonationEvent = bookDonationEventRepository.findById(donationId).orElseThrow( () -> new IllegalArgumentException("해당 이벤트가 존재하지 않습니다.") ); List<Book> books = bookDonationEvent.getBooks().stream().filter(book -> book.getBookStatus().equals(BookStatusEnum.DONATION)).toList(); List<BookResponseDto> bookResponseDtos = books.stream() .map(BookResponseDto::new) .toList(); BookDonationEventResponseDto bookDonationEventResponseDto = new BookDonationEventResponseDto(bookDonationEvent); model.addAttribute("bookDonationEvent", bookDonationEventResponseDto); model.addAttribute("books", bookResponseDtos); return "/users/bookApplyDonation"; }
Java
복사
@Query(value = "select bde from BookDonationEvent bde" + " join fetch bde.books book" + " where bde.id = :donationId and book.bookStatus = :status") Page<BookDonationEvent> findPageByDonationId(@Param("donationId") Long donationId, @Param("status") BookStatusEnum status, Pageable pageable);
Java
복사

원인 분석

페이징 처리의 복잡성

JPA의 페이징 처리는 논리적으로 간단하지만 join fetch를 사용하면서 발생하는 문제는 각 BookDonationEvent가 여러 Book을 가질 수 있기 때문이다. 따라서 한 BookDonationEvent 내부의 여러 Book들이 페이징 처리의 대상이 되면서 원하는 페이징 결과를 얻기 어려웠던 것 같다.

해결

적절한 페이징 처리

BookDonationEvent를 중심으로 페이징하는 대신 직접적으로 Book을 조회하는 방식으로 쿼리를 변경하여 문제를 해결했다. 이 방식을 사용하면 BookDonationEvent에 종속되지 않고 원하는 조건과 함께 Book만을 페이징 처리하여 결과를 얻을 수 있다.