Conversation
Walkthrough베팅 라운드와 가격 데이터 조회 로직을 최신 레코드 기준으로 변경합니다. 저장소 메서드명을 Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant BettingController
participant BettingService
participant BetRoundRepository
participant PriceDataRepository
Note over BettingController,PriceDataRepository: 이전 흐름: 임의 데이터 선택
Client->>BettingController: getTodayBetRound()
BettingController->>BettingService: getActiveRound()
BettingService->>BetRoundRepository: findByStatusTrueAndScope()
Note over BettingService: 임의의 활성 라운드 반환
Note over BettingController,PriceDataRepository: 변경 흐름: 최신 데이터 우선
Client->>BettingController: getTodayBetRound()
BettingController->>BettingService: getActiveRound()
BettingService->>BetRoundRepository: findTopByStatusTrueAndScopeOrderByOpenAtDesc()
Note over BettingService: 최신 OpenAt 기준 라운드 반환
BettingService->>PriceDataRepository: findAll()
Note over BettingService: 모든 가격 데이터 조회
BettingService->>BettingService: 임의 ticker 선택
BettingService->>PriceDataRepository: findTopByTickerOrderByDateDesc(randomTicker)
Note over BettingService: 선택된 ticker의 최신 가격 데이터 반환
BettingService-->>Client: 최신 데이터 기반 응답
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12분
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ 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
🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/betting/service/BettingService.java (1)
78-78: 불필요한 빈 줄 추가.Line 78에 변경된 빈 줄이 있습니다. 의도하지 않은 변경인 경우 제거하는 것이 좋습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
backend/src/main/java/org/sejongisc/backend/betting/controller/BettingController.java(0 hunks)backend/src/main/java/org/sejongisc/backend/betting/repository/BetRoundRepository.java(1 hunks)backend/src/main/java/org/sejongisc/backend/betting/service/BettingService.java(3 hunks)backend/src/main/java/org/sejongisc/backend/stock/repository/PriceDataRepository.java(1 hunks)
💤 Files with no reviewable changes (1)
- backend/src/main/java/org/sejongisc/backend/betting/controller/BettingController.java
🔇 Additional comments (5)
backend/src/main/java/org/sejongisc/backend/stock/repository/PriceDataRepository.java (1)
16-16: 메서드명 변경이 적절합니다.
findFirst에서findTop으로 변경되었지만 Spring Data JPA에서 두 키워드는 동일한 동작을 합니다. 일관된 네이밍 규칙을 위한 변경으로 보입니다.backend/src/main/java/org/sejongisc/backend/betting/service/BettingService.java (3)
39-41: 저장소 메서드 호출이 올바르게 업데이트되었습니다.변경된 저장소 메서드를 정확히 호출하고 있습니다. 이제 가장 최근에 열린 활성 라운드를 조회합니다.
211-211: 저장소 메서드 호출이 올바르게 업데이트되었습니다.
findFirstByTickerOrderByDateDesc에서findTopByTickerOrderByDateDesc로 변경되었으며, Spring Data JPA에서는 동일하게 동작합니다.
69-75: 검토: 이 리뷰 코멘트는 부정확합니다.PriceData 엔티티에는 회사명 필드가 없습니다. 확인된 PriceData 필드는 다음과 같습니다: ticker, date, open, high, low, closePrice, volume, adjustedClose.
현재 코드는 PriceData에서 유일하게 사용 가능한 식별자인 ticker를 name과 symbol로 사용하고 있으며, 이는 올바른 구현입니다. 리뷰 코멘트의 제안은 기존 엔티티 구조에 적용할 수 없습니다.
Likely an incorrect or invalid review comment.
backend/src/main/java/org/sejongisc/backend/betting/repository/BetRoundRepository.java (1)
13-13: 메서드 변경사항 검증 완료 - 이상 없음메서드 시그니처 변경(
findByStatusTrueAndScope→findTopByStatusTrueAndScopeOrderByOpenAtDesc)은 의도된 개선입니다:
- 기존 동작: 조건 일치 라운드 중 비결정적 반환 (Hibernate 기본 동작)
- 개선된 동작: 가장 최근 개설 라운드만 결정적으로 반환 (
openAt역순)
closeBetRound()는lockAt시점에 도달한 라운드를 자동으로 비활성화하므로, 정상 운영 중에는 scope당 하나의 활성 라운드만 존재합니다. 새로운 쿼리는 엣지 케이스(동시성 문제 등)에서도 예측 가능한 동작을 보장합니다.
| List<PriceData> allData = priceDataRepository.findAll(); | ||
| if (allData.isEmpty()) { | ||
| throw new CustomException(ErrorCode.STOCK_NOT_FOUND); | ||
| } | ||
|
|
||
| PriceData price = priceList.get(random.nextInt(priceList.size())); | ||
| List<String> tickers = allData.stream() | ||
| .map(PriceData::getTicker) | ||
| .distinct() | ||
| .toList(); | ||
|
|
||
| String randomTicker = tickers.get(random.nextInt(tickers.size())); | ||
|
|
||
| PriceData latest = priceDataRepository.findTopByTickerOrderByDateDesc(randomTicker) | ||
| .orElseThrow(() -> new CustomException(ErrorCode.STOCK_NOT_FOUND)); |
There was a problem hiding this comment.
성능 문제: 전체 데이터 로드를 피하세요.
현재 구현은 findAll()로 모든 PriceData를 메모리에 로드한 후 distinct ticker를 추출합니다. PriceData 테이블에 수천~수만 개의 레코드가 있는 경우 심각한 성능 저하가 발생할 수 있습니다.
다음과 같이 개선하는 것을 권장합니다:
방법 1: Repository에 distinct ticker 조회 메서드 추가 (권장)
PriceDataRepository에 메서드 추가:
@Query("SELECT DISTINCT p.ticker FROM PriceData p")
List<String> findDistinctTickers();그 후 서비스 코드 수정:
- List<PriceData> allData = priceDataRepository.findAll();
- if (allData.isEmpty()) {
+ List<String> tickers = priceDataRepository.findDistinctTickers();
+ if (tickers.isEmpty()) {
throw new CustomException(ErrorCode.STOCK_NOT_FOUND);
}
- List<String> tickers = allData.stream()
- .map(PriceData::getTicker)
- .distinct()
- .toList();
-
String randomTicker = tickers.get(random.nextInt(tickers.size()));방법 2: Native Query 사용
@Query(value = "SELECT DISTINCT ticker FROM price_data", nativeQuery = true)
List<String> findDistinctTickers();🤖 Prompt for AI Agents
In
backend/src/main/java/org/sejongisc/backend/betting/service/BettingService.java
around lines 54 to 67, avoid loading all PriceData via findAll() — add a
repository method to fetch distinct tickers (either JPQL or native query) and
call that instead, then pick a random ticker from the returned list and query
for the latest PriceData for that ticker; update the service to use the new
repository method (handle empty result with the same CustomException) so only
ticker values are loaded into memory rather than all PriceData rows.
Summary by CodeRabbit
출시 노트