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

song yuheon·2023년 10월 19일
0

Trouble Shooting

목록 보기
36/57
post-thumbnail

문제 상황

  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";
    }
@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);

원인 분석

페이징 처리의 복잡성

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

해결

적절한 페이징 처리

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


profile
backend_Devloper

0개의 댓글