Conversation
|
Caution Review failedThe pull request is closed. Walkthrough이 PR은 Redis 캐싱 인프라를 추가하고 시설 및 포스트 도메인에 캐싱 기능을 구현합니다. Spring Boot Redis/Cache 의존성을 추가하고, 캐시 키 생성 인터페이스와 구현체들을 도입하며, TTL 설정을 포함한 Redis 캐시 구성을 새로 생성합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Controller
participant Service
participant Cache as Redis Cache
participant Repository
participant Mapper
Client->>Controller: getNear(FacilityNearRequest)
Controller->>Service: getNear(request)
Service->>Service: generateCacheKey()
Service->>Cache: check cache key
alt Cache Hit
Cache-->>Service: FacilityNearResponse list
else Cache Miss
Service->>Repository: findNearby(lat, lng, radius)
Repository-->>Service: List<Facility>
Service->>Mapper: map to FacilityNearResponse
Mapper-->>Service: FacilityNearResponse list
Service->>Cache: store with TTL (60s)
end
Service-->>Controller: FacilityNearResponse list
Controller-->>Client: BaseResponse<List<FacilityNearResponse>>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/main/java/com/be/sportizebe/domain/facility/dto/request/FacilityMarkerRequest.java (1)
27-47:⚠️ Potential issue | 🟡 MinorradiusM/limit의 null 입력과 Locale에 따른 캐시 키 불안정성 개선
@Min/@max 제약조건은 null 값을 검증하지 않으므로, radiusM과 limit이 null일 경우 generateCacheKey()의 %d 언박싱에서 NPE가 발생할 수 있습니다. 또한 Locale.ROOT를 지정하지 않으면 String.format()이 시스템 로케일에 따라 소수점 구분자가 변경되어 (예: fr_FR에서는 "37,2869", en_US에서는 "37.2869") 캐시 키의 일관성이 깨질 수 있습니다.
@NotNull추가와 Locale.ROOT 지정으로 개선하세요. FacilityNearRequest도 동일한 패턴을 사용하므로 함께 적용하세요.제안 변경
`@Schema`(description = "반경(미터)", example = "5000", defaultValue = "5000") + `@NotNull`(message = "반경은 필수입니다") `@Min`(value = 100, message = "반경은 최소 100m 이상이어야 합니다") `@Max`(value = 20000, message = "반경은 최대 20km까지 가능합니다") private Integer radiusM = 5000; `@Schema`(description = "조회 개수 제한", example = "200", defaultValue = "200") + `@NotNull`(message = "limit는 필수입니다") `@Min`(value = 1, message = "limit는 최소 1 이상이어야 합니다") `@Max`(value = 500, message = "limit는 최대 500까지 가능합니다") private Integer limit = 200; `@Override` public String generateCacheKey() { double gridLat = Math.round(this.lat * 10000) / 10000.0; double gridLng = Math.round(this.lng * 10000) / 10000.0; String typeName = (type == null) ? "ALL" : type.name(); - return String.format("%.4f:%.4f:%d:%d:%s", + return String.format(java.util.Locale.ROOT, "%.4f:%.4f:%d:%d:%s", gridLat, gridLng, radiusM, limit, typeName);src/main/java/com/be/sportizebe/domain/facility/dto/request/FacilityNearRequest.java (1)
27-48:⚠️ Potential issue | 🟡 Minor캐시 키 생성 시 null 처리와 Locale 안정화 필요
radiusM/limit이 Integer 래퍼 타입이면서
@NotNull없이 명시적으로 null로 설정될 경우 String.format의 %d 언박싱에서 NPE가 발생할 수 있습니다. 또한 String.format은 JVM 기본 Locale에 따라 소수점 구분자가 달라져(미국은., 유럽은,) 캐시 키의 일관성이 깨질 수 있습니다. 각 필드에@NotNull을추가하고 String.format에 Locale.ROOT를 명시하여 안정화하세요.제안 변경
- `@Min`(value = 100, message = "반경은 최소 100m 이상이어야 합니다") - `@Max`(value = 10000, message = "반경은 최대 10km까지 가능합니다") - private Integer radiusM = 3000; + `@NotNull`(message = "반경은 필수입니다") + `@Min`(value = 100, message = "반경은 최소 100m 이상이어야 합니다") + `@Max`(value = 10000, message = "반경은 최대 10km까지 가능합니다") + private Integer radiusM = 3000; - `@Min`(value = 1, message = "limit는 최소 1 이상이어야 합니다") - `@Max`(value = 100, message = "limit는 최대 100까지 가능합니다") - private Integer limit = 50; + `@NotNull`(message = "limit는 필수입니다") + `@Min`(value = 1, message = "limit는 최소 1 이상이어야 합니다") + `@Max`(value = 100, message = "limit는 최대 100까지 가능합니다") + private Integer limit = 50; - return String.format("%.4f:%.4f:%d:%d:%s", + return String.format(java.util.Locale.ROOT, "%.4f:%.4f:%d:%d:%s", gridLat, gridLng, radiusM, limit, typeName);동일한 문제가 FacilityMarkerRequest.java에도 있습니다.
🤖 Fix all issues with AI agents
In
`@src/main/java/com/be/sportizebe/domain/facility/service/SportsFacilityService.java`:
- Line 12: The inline comment on the getNear method contains a typo ("조히") — in
the SportsFacilityService interface update the comment for the method
List<FacilityNearResponse> getNear(FacilityNearRequest request) to read "현재 위치
기준 반경 내 체육시설을 거리순으로 조회" (replace "조히" with "조회"); simply correct the Korean
comment text adjacent to the getNear method declaration.
🧹 Nitpick comments (2)
src/main/java/com/be/sportizebe/global/config/RedisCacheConfig.java (1)
26-45: 캐시 ObjectMapper를 공용 빈에 맞춰 설정 드리프트를 줄여주세요.현재 캐시 전용 ObjectMapper를 새로 만들어 JacksonConfig와 설정이 분리될 수 있습니다. 공용 ObjectMapper를 주입받아 copy() 후 필요한 모듈만 추가하는 방식이 유지보수에 안전합니다. 또한 “타입 정보 포함” 주석은 실제 동작과 어긋나니 정정이 필요합니다.
♻️ 제안 변경
- public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { - // 캐시 역직렬화를 위해 타입 정보(`@class`)를 포함하도록 설정 - ObjectMapper objectMapper = JsonMapper.builder() - .addModule(new JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - // ❗ 타입 정보 절대 쓰지 않음 - .build(); + public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ObjectMapper objectMapper) { + // 캐시 직렬화 전용 설정(공용 ObjectMapper 기반) + ObjectMapper cacheObjectMapper = objectMapper.copy() + .registerModule(new JavaTimeModule()) + .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);- defaultValueSerializer.setObjectMapper(objectMapper); + defaultValueSerializer.setObjectMapper(cacheObjectMapper); ... - postListValueSerializer.setObjectMapper(objectMapper); + postListValueSerializer.setObjectMapper(cacheObjectMapper);src/main/java/com/be/sportizebe/global/cache/PostListKeyGenerator.java (1)
14-18: KeyGenerator 파라미터 검증으로 실패 원인을 명확히 해주세요.현재는 params 길이/타입이 다르면 ClassCastException이 발생합니다. 명시적 검증으로 빠르게 실패하도록 하는 편이 안전합니다.
♻️ 제안 변경
`@Override` public Object generate(Object target, Method method, Object... params) { - - PostProperty property = (PostProperty) params[0]; - Pageable pageable = (Pageable) params[1]; + if (params.length < 2 + || !(params[0] instanceof PostProperty) + || !(params[1] instanceof Pageable)) { + throw new IllegalArgumentException("postListKeyGenerator expects (PostProperty, Pageable)"); + } + PostProperty property = (PostProperty) params[0]; + Pageable pageable = (Pageable) params[1];
| public interface SportsFacilityService { | ||
|
|
||
| private final SportsFacilityRepository sportsFacilityRepository; | ||
| List<FacilityNearResponse> getNear(FacilityNearRequest request); // 현재 위치 기준 반경 내 체육시설을 거리순으로 조히 |
There was a problem hiding this comment.
주석 오탈자 수정 제안(“조히” → “조회”).
✍️ 수정 제안
- List<FacilityNearResponse> getNear(FacilityNearRequest request); // 현재 위치 기준 반경 내 체육시설을 거리순으로 조히
+ List<FacilityNearResponse> getNear(FacilityNearRequest request); // 현재 위치 기준 반경 내 체육시설을 거리순으로 조회📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| List<FacilityNearResponse> getNear(FacilityNearRequest request); // 현재 위치 기준 반경 내 체육시설을 거리순으로 조히 | |
| List<FacilityNearResponse> getNear(FacilityNearRequest request); // 현재 위치 기준 반경 내 체육시설을 거리순으로 조회 |
🤖 Prompt for AI Agents
In
`@src/main/java/com/be/sportizebe/domain/facility/service/SportsFacilityService.java`
at line 12, The inline comment on the getNear method contains a typo ("조히") — in
the SportsFacilityService interface update the comment for the method
List<FacilityNearResponse> getNear(FacilityNearRequest request) to read "현재 위치
기준 반경 내 체육시설을 거리순으로 조회" (replace "조히" with "조회"); simply correct the Korean
comment text adjacent to the getNear method declaration.
#️⃣ Issue Number
📝 요약(Summary)
Redis 캐시를 도입하면서 발생한 게시글 목록 조회(postList) 역직렬화 오류를 해결하고,
facility API와 post API의 캐시 전략을 분리하여 안정적으로 동작하도록 개선했습니다.
🛠️ PR 유형
어떤 변경 사항이 있나요?
📸스크린샷 (선택)
💬 공유사항 to 리뷰어
postList 캐시는 전용 DTO(PostPageResponse)로 직렬화 방식을 분리했습니다.
✅ PR Checklist
PR이 다음 요구 사항을 충족하는지 확인하세요.
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선 사항
의존성
✏️ Tip: You can customize this high-level summary in your review settings.