[fix] 저장한 책 또는 참여 중 모임의 책 조회 쿼리 수정#253
Conversation
WalkthroughBookJpaRepository의 두 메서드(@query) JPQL을 수정하여 DISTINCT 기반 정렬을 그룹화(GROUP BY)와 집계(MAX) 정렬로 변경했습니다. 저장한 책 조회는 최신 저장일 기준, 참여 중 모임의 책 조회는 최대 진행률 기준으로 정렬되도록 쿼리만 갱신했습니다. 시그니처 변경은 없습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Service
participant BookJpaRepository
participant DB
Service->>BookJpaRepository: findSavedBooksByUserId(userId)
BookJpaRepository->>DB: SELECT b GROUP BY b ORDER BY MAX(s.createdAt) DESC
DB-->>BookJpaRepository: List<Book>
BookJpaRepository-->>Service: List<Book>
sequenceDiagram
participant Service
participant BookJpaRepository
participant DB
Service->>BookJpaRepository: findJoiningRoomsBooksByUserId(userId)
BookJpaRepository->>DB: SELECT b WHERE userId, r.status='ACTIVE', r.startDate<=NOW GROUP BY b ORDER BY MAX(r.roomPercentage) DESC
DB-->>BookJpaRepository: List<Book>
BookJpaRepository-->>Service: List<Book>
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes(해당 없음) Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
Test Results407 tests 407 ✅ 30s ⏱️ Results for commit 6d65d77. |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
src/main/java/konkuk/thip/book/adapter/out/persistence/repository/BookJpaRepository.java (5)
14-17: id 비교 대신 연관 엔티티 비교로 JOIN 단순화 + 안정적 2차 정렬 제안
- JPQL에서는 id 직접 비교보다 연관 엔티티 동등성 비교가 더 간결하고 리팩토링에 안전합니다.
- 동률 시 결과 순서가 비결정적일 수 있으니, 2차 정렬 키를 추가하면 안정성이 좋아집니다.
아래와 같이 변경을 고려해 주세요:
- "JOIN SavedBookJpaEntity s ON s.bookJpaEntity.bookId = b.bookId " + + "JOIN SavedBookJpaEntity s ON s.bookJpaEntity = b " + ... - "ORDER BY MAX(s.createdAt) DESC") + "ORDER BY MAX(s.createdAt) DESC, b.bookId DESC")
21-27: JOIN 단순화(엔티티 동등성) + 정렬 안정성(2차 키) 개선 제안
- r.bookJpaEntity도 id 비교 대신 엔티티 동등성 비교가 가독성/안정성 측면에서 유리합니다.
- 동률 시 결과 불안정성을 줄이기 위해 2차 정렬 키를 추가하는 것을 권장합니다.
- "JOIN RoomJpaEntity r ON r.bookJpaEntity.bookId = b.bookId " + + "JOIN RoomJpaEntity r ON r.bookJpaEntity = b " + ... - "ORDER BY MAX(r.roomPercentage) DESC") // 방의 진행률이 높은 순서로 정렬 + "ORDER BY MAX(r.roomPercentage) DESC, b.bookId DESC") // 동률 시 bookId로 안정 정렬
13-27: 성능: 조인/필터/정렬 컬럼 인덱스 점검 권장GROUP BY + MAX 정렬은 의도대로 작동하지만, 데이터량이 커지면 조인과 그룹 연산 비용이 커집니다. 아래 컬럼들에 대한 인덱스를 확인/추가하면 도움이 됩니다.
- SavedBookJpaEntity: (user_id, book_id), (user_id, created_at DESC)
- RoomParticipantJpaEntity: (user_id, room_id) 또는 최소 (user_id)
- RoomJpaEntity: (book_id, status, start_date), 필요 시 (book_id, room_percentage)
DB 설계 상 이미 존재한다면 스킵 가능합니다.
13-28: 레포지토리 테스트 보강 제안다음 시나리오를 커버하는 테스트를 추가하면 회귀를 막을 수 있습니다.
- 저장한 책 조회: 같은 책을 여러 번 저장해도 1건만 반환, 최신 저장일 기준 정렬 검증.
- 참여 중 모임 책 조회: 한 책에 여러 방 참여 시 MAX(roomPercentage)로 정렬되는지, 비활성/시작 전 방이 제외되는지 검증.
- 정렬 동률 케이스(동일 createdAt/roomPercentage)에서 결과 안정성 확인.
필요하시면 테스트 템플릿 제공 가능합니다.
24-25: BookJpaRepository: JPQL 하드코딩 ENUM 및 날짜 비교 개선 제안
- BaseJpaEntity에서
status는@Enumerated(EnumType.STRING)으로 매핑되어 있어 현재는'ACTIVE'직접 비교가 가능하지만, 향후 매핑 방식을 변경할 때 깨질 위험이 있습니다. 아래 중 하나로 타입 세이프하게 전환을 권장드립니다.
• 파라미터 바인딩:• JPQL enum 상수 FQN 직접 참조:… WHERE rp.userJpaEntity.userId = :userId AND r.status = :status AND r.startDate <= CURRENT_DATE … List<BookJpaEntity> findJoiningRoomsBooksByUserId( @Param("userId") Long userId, @Param("status") StatusType status);… AND r.status = konkuk.thip.common.entity.StatusType.ACTIVE …RoomJpaEntity.startDate가LocalDate타입이므로,CURRENT_TIMESTAMP대신CURRENT_DATE를 사용해 불필요한 시간 단위 오차를 방지하는 것이 바람직합니다.- AND r.startDate <= CURRENT_TIMESTAMP + AND r.startDate <= CURRENT_DATE
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/main/java/konkuk/thip/book/adapter/out/persistence/repository/BookJpaRepository.java(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (2)
src/main/java/konkuk/thip/book/adapter/out/persistence/repository/BookJpaRepository.java (2)
13-17: DISTINCT → GROUP BY + MAX 전환으로 정렬 오류 해결: 👍DISTINCT로 인해 ORDER BY가 상쇄되던 문제를 GROUP BY와 집계 정렬로 올바르게 풀었습니다. 목적(최신 저장일 기준 정렬)과 쿼리의 의미가 일치합니다.
20-27: 참여 중 모임 책 조회도 GROUP BY + MAX로 의도 준수: 👍여러 방에 참여한 경우에도 도서 단위로 그룹화하고 진행률의 최대값으로 정렬하려는 의도가 정확히 반영되었습니다.
#️⃣ 연관된 이슈
📝 작업 내용
개발서버에서 DISTINCT 문에 의해서 오류가 발생하고 있어, 고민을 해보니 정렬을 SavedBook과 RoomParticipant 필드로 하고 있는데 Book을 조회하면서 DISTINCT문을 사용하고 있기 때문에 정렬 조건이 상쇄되는 문제가 있어서 500 에러가 뜨는 걸로 추정하였습니다.
따라서, group by와 집계합수 max를 사용하는 방식으로 수정하였습니다.
📸 스크린샷
💬 리뷰 요구사항
📌 PR 진행 시 이러한 점들을 참고해 주세요
Summary by CodeRabbit