From 9007bd65937fcb920bcd97b31bf818c25336bc61 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 16 Mar 2026 15:46:37 +0900 Subject: [PATCH] =?UTF-8?q?fix(can):=20=EC=BA=94=20=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EB=82=B4=EC=97=AD=20=EC=A1=B0=ED=9A=8C=20DISTINCT=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=EB=A5=BC=20=EC=88=98=EC=A0=95=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/20260316_캔사용내역조회DISTINCT오류수정.md | 16 ++++++++++++++++ .../co/vividnext/sodalive/can/CanRepository.kt | 1 + .../co/vividnext/sodalive/can/UseCanQueryDto.kt | 1 + .../co/vividnext/sodalive/can/CanServiceTest.kt | 4 +++- 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 docs/20260316_캔사용내역조회DISTINCT오류수정.md diff --git a/docs/20260316_캔사용내역조회DISTINCT오류수정.md b/docs/20260316_캔사용내역조회DISTINCT오류수정.md new file mode 100644 index 00000000..1c2ad0d3 --- /dev/null +++ b/docs/20260316_캔사용내역조회DISTINCT오류수정.md @@ -0,0 +1,16 @@ +# 20260316_캔사용내역조회DISTINCT오류수정.md + +## 구현 목표 +- `CanRepository.getCanUseStatus` 호출 시 발생하는 `java.sql.SQLException` (DISTINCT와 ORDER BY 충돌)을 해결한다. + +## 작업 내용 +- [x] `UseCanQueryDto.kt`에 `id: Long` 필드 추가 +- [x] `CanRepository.kt`의 `getCanUseStatus` 쿼리 `select` 절에 `useCan.id` 추가 +- [x] `CanServiceTest.kt`의 `UseCanQueryDto` 생성자 호출 로직에 `id` 추가 +- [x] `./gradlew ktlintFormat` 실행 및 스타일 확인 +- [x] `./gradlew test` 실행하여 검증 + +## 검증 결과 +- 무엇을: 캔 사용 내역 조회 API +- 왜: `DISTINCT` 사용 시 `ORDER BY` 컬럼(`id`)이 `SELECT` 목록에 없어 발생하는 런타임 오류 해결 +- 어떻게: `id`를 DTO에 포함시켜 `SELECT` 목록에 노출되도록 수정 diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/CanRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/CanRepository.kt index 97ffa77d..cadeb48f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/can/CanRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/CanRepository.kt @@ -91,6 +91,7 @@ class CanQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : CanQue return queryFactory .select( QUseCanQueryDto( + useCan.id, useCan.canUsage, useCan.can, useCan.rewardCan, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/UseCanQueryDto.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/UseCanQueryDto.kt index c11bab22..4bcb5e00 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/can/UseCanQueryDto.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/UseCanQueryDto.kt @@ -5,6 +5,7 @@ import kr.co.vividnext.sodalive.can.use.CanUsage import java.time.LocalDateTime data class UseCanQueryDto @QueryProjection constructor( + val id: Long, val canUsage: CanUsage, val can: Int, val rewardCan: Int, diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/can/CanServiceTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/can/CanServiceTest.kt index 977294a6..cbfcef2c 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/can/CanServiceTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/can/CanServiceTest.kt @@ -145,9 +145,11 @@ class CanServiceTest { audioContentTitle: String? = null, communityPostMemberNickname: String? = null, auditionTitle: String? = null, - characterName: String? = null + characterName: String? = null, + id: Long = 1L ): UseCanQueryDto { return UseCanQueryDto( + id = id, canUsage = usage, can = can, rewardCan = rewardCan,