Conversation
WalkthroughAudioGuideRepository에 콘텐츠 ID 목록으로 오디오 가이드 존재 콘텐츠를 배치 조회하는 JPQL 메서드가 추가되었고, SpotServiceImpl.getNearbySpotsWithAudioGuides는 개별 exists 호출을 일괄 조회 후 Set으로 필터링하도록 변경되었다. NearbyAudioSpotResponse에서 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant SpotService as SpotServiceImpl
participant SpotRepo as SpotRepository
participant AudioRepo as AudioGuideRepository
Client->>SpotService: getNearbySpotsWithAudioGuides(params)
SpotService->>SpotRepo: findNearbySpots(params)
SpotRepo-->>SpotService: List<Spot>
SpotService->>SpotService: extract allSpotIds
rect rgba(210,235,255,0.4)
note over SpotService,AudioRepo: 배치 조회로 오디오 가이드 존재 콘텐츠 ID 가져오기
SpotService->>AudioRepo: findContentIdsWithAudioGuidesByContentIdIn(allSpotIds)
AudioRepo-->>SpotService: List<Long> contentIds
end
SpotService->>SpotService: Set<Long> ids = new HashSet<>(contentIds)
SpotService->>SpotService: filter spots by ids.contains(spotId)
SpotService-->>Client: Filtered SpotResponses
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
💤 Files with no reviewable changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Test Results0 tests 0 ✅ 0s ⏱️ Results for commit 4feb455. ♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/main/java/com/yfive/gbjs/domain/guide/repository/AudioGuideRepository.java (1)
40-42: 배치 조회 메서드 추가 좋습니다. 시그니처를 Set/Collection 기반으로 다듬는 것을 제안합니다.
- 반환 타입을 Set으로 두면 DISTINCT 의미와 일치하고, 호출부에서 별도 HashSet 래핑이 불필요합니다.
- 파라미터는 List보다 Collection이 유연합니다.
아래처럼 변경하면 호출부 단순화 + 불필요한 중복 제거 효과가 있습니다.
- @Query("SELECT DISTINCT ag.contentId FROM AudioGuide ag WHERE ag.contentId IN :contentIds") - List<Long> findContentIdsWithAudioGuidesByContentIdIn(@Param("contentIds") List<Long> contentIds); + @Query("SELECT DISTINCT ag.contentId FROM AudioGuide ag WHERE ag.contentId IN :contentIds") + java.util.Set<Long> findContentIdsWithAudioGuidesByContentIdIn( + @Param("contentIds") java.util.Collection<Long> contentIds);추가로, JPA 구현체에 따라 빈 컬렉션으로 IN 절을 호출하면 예외가 날 수 있으므로(예: IN ()) 호출부에서 빈 컬렉션은 바로 빈 결과를 반환하도록 가드해 주세요.
빈 컬렉션 가드가 필요한지 확인하고 싶다면 DB 벤더/버전을 공유해 주세요(Oracle의 IN 파라미터 개수 제한도 고려 필요).
src/main/java/com/yfive/gbjs/domain/spot/service/SpotServiceImpl.java (2)
432-439: 빈/중복/널 ID 가드 + 호출 단순화로 안전성과 효율 개선
- spotId 중복·널을 미리 제거하고 빈 경우 즉시 반환하면 불필요한 DB 호출을 막습니다.
- 저장소 메서드가 List만 받는 경우가 아니라면 Collection으로 바꾸고 호출부 래핑을 제거하는 것이 깔끔합니다(레포 시그니처 변경 제안과 연계).
- // 1. 모든 spotId를 추출 - List<Long> allSpotIds = - allSpots.stream().map(SpotResponse::getSpotId).collect(Collectors.toList()); - - // 2. 추출된 spotId 목록으로 오디오 가이드가 존재하는 contentId들을 한 번에 조회 - Set<Long> contentIdsWithAudioGuides = - new HashSet<>(audioGuideRepository.findContentIdsWithAudioGuidesByContentIdIn(allSpotIds)); + // 1. 모든 spotId를 추출(널 제거 + 중복 제거) + java.util.Set<Long> allSpotIds = allSpots.stream() + .map(SpotResponse::getSpotId) + .filter(java.util.Objects::nonNull) + .collect(Collectors.toSet()); + if (allSpotIds.isEmpty()) { + return java.util.List.of(); + } + + // 2. 배치 조회 + java.util.Set<Long> contentIdsWithAudioGuides = + new java.util.HashSet<>(audioGuideRepository + .findContentIdsWithAudioGuidesByContentIdIn(new java.util.ArrayList<>(allSpotIds)));레포가 제안대로
Collection/Set시그니처로 바뀌면 위 호출부는 아래처럼 더 단순해집니다(참고):Set<Long> contentIdsWithAudioGuides = audioGuideRepository.findContentIdsWithAudioGuidesByContentIdIn(allSpotIds);
- DB가 Oracle 등 IN 파라미터 개수 제한(예: 1000)이 있는지 확인 부탁드립니다. 제한이 있다면 allSpotIds를 청크로 나눠 쿼리 후 합치는 처리가 필요합니다. 필요 시 청크 유틸 제공 가능합니다.
445-446: 정렬 전에 필터링하여 작업량 감소필터링을 먼저 수행하면 비교/정렬 대상이 줄어 성능이 나아집니다(최대 1000건 정렬 → 오디오가이드 존재 건만 정렬).
- return allSpots.stream() - .sorted( - Comparator.comparing( - SpotResponse::getDistance, Comparator.nullsLast(Double::compareTo))) - .filter( - // 3. Set을 사용하여 메모리에서 빠르게 필터링 - spot -> contentIdsWithAudioGuides.contains(spot.getSpotId())) + return allSpots.stream() + // 3. Set을 사용하여 메모리에서 빠르게 필터링 + .filter(spot -> contentIdsWithAudioGuides.contains(spot.getSpotId())) + .sorted( + Comparator.comparing( + SpotResponse::getDistance, Comparator.nullsLast(Double::compareTo)))
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/main/java/com/yfive/gbjs/domain/guide/repository/AudioGuideRepository.java(1 hunks)src/main/java/com/yfive/gbjs/domain/spot/service/SpotServiceImpl.java(2 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 and Test
🔇 Additional comments (2)
src/main/java/com/yfive/gbjs/domain/spot/service/SpotServiceImpl.java (1)
10-13: 새 import 추가 OKHashSet, Set, Collectors 사용과 일치합니다. 불필요한 import 없음.
src/main/java/com/yfive/gbjs/domain/guide/repository/AudioGuideRepository.java (1)
40-42: content_id 단일 컬럼 인덱스 추가 권장src/main/java/com/yfive/gbjs/domain/guide/entity/AudioGuide.java의 AudioGuide 엔티티에 content_id에 대한 @table(indexes=...) / @Index 정의가 없고 레포에서 마이그레이션/DDL 파일도 발견되지 않았습니다. 트래픽이 많은 핫패스일 가능성이 있으니 audio_guide.content_id에 단일 컬럼 인덱스 추가(엔티티의 @table(indexes = @Index(columnList = "content_id")) 또는 DB 마이그레이션)를 적용하세요.
Summary by CodeRabbit