-
Notifications
You must be signed in to change notification settings - Fork 1
fix: 탈퇴한 유저 재가입 시 기존 정보 복구되지 않는 문제 해결 #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ package org.yapp.infra.user.repository | |
|
|
||
| import org.springframework.data.jpa.repository.JpaRepository | ||
| import org.springframework.data.jpa.repository.Query | ||
| import org.springframework.data.repository.query.Param | ||
| import org.yapp.domain.user.ProviderType | ||
| import org.yapp.infra.user.entity.UserEntity | ||
| import java.util.* | ||
|
|
@@ -15,6 +16,12 @@ interface JpaUserRepository : JpaRepository<UserEntity, UUID> { | |
|
|
||
| fun existsByEmail(email: String): Boolean | ||
|
|
||
| @Query("SELECT u FROM UserEntity u WHERE u.providerType = :providerType AND u.providerId = :providerId") | ||
| fun findByProviderTypeAndProviderIdIncludingDeleted(providerType: ProviderType, providerId: String): UserEntity? | ||
| @Query( | ||
| value = "SELECT * FROM users u WHERE u.provider_type = :providerType AND u.provider_id = :providerId", | ||
| nativeQuery = true | ||
| ) | ||
| fun findByProviderTypeAndProviderIdIncludingDeleted( | ||
| @Param("providerType") providerType: String, | ||
| @Param("providerId") providerId: String | ||
| ): UserEntity? | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain중복 레코드 존재 시 단일 결과 요구로 인한 런타임 에러 위험 (NonUniqueResultException/IncorrectResultSizeDataAccessException) 해당 버그로 이미 “soft-deleted + 새로 가입된 활성”의 중복이 존재할 수 있습니다. 현재 메서드는 단일 엔티티를 반환하도록 되어 있어, 두 건 이상이 반환되면 런타임 예외가 발생할 수 있습니다. 최소한 결정적 정렬과 1건 제한을 추가해 주세요.
예시 diff: - @Query(
- value = "SELECT * FROM users u WHERE u.provider_type = :providerType AND u.provider_id = :providerId",
- nativeQuery = true
- )
+ @Query(
+ value = """
+ SELECT u.*
+ FROM users u
+ WHERE u.provider_type = :providerType
+ AND u.provider_id = :providerId
+ ORDER BY CASE WHEN u.deleted_at IS NULL THEN 0 ELSE 1 END, u.updated_at DESC
+ FETCH FIRST 1 ROW ONLY
+ """,
+ nativeQuery = true
+ )검증 스크립트(메서드 사용처 파악 및 정책 결정에 참고): 정책이 확정되지 않았다면, 반환 타입을 List로 바꾸고 상위 계층에서 해석(복구/병합/경고)하는 방안을 고려할 수도 있습니다. 🏁 Script executed: #!/bin/bash
# 메서드 사용처 확인
rg -n -C3 '\bfindByProviderTypeAndProviderIdIncludingDeleted\s*\('Length of output: 3644 중복 레코드로 인한 NonUniqueResultException 방지: ORDER BY + LIMIT 추가 필수 수정 대상:
설명: 예시 diff: @@ infra/src/main/kotlin/org/yapp/infra/user/repository/JpaUserRepository.kt
- @Query(
- value = "SELECT * FROM users u WHERE u.provider_type = :providerType AND u.provider_id = :providerId",
- nativeQuery = true
- )
+ @Query(
+ value = """
+ SELECT u.*
+ FROM users u
+ WHERE u.provider_type = :providerType
+ AND u.provider_id = :providerId
+ ORDER BY CASE WHEN u.deleted_at IS NULL THEN 0 ELSE 1 END, u.updated_at DESC
+ FETCH FIRST 1 ROW ONLY
+ """,
+ nativeQuery = true
+ )
fun findByProviderTypeAndProviderIdIncludingDeleted(
@Param("providerType") providerType: String,
@Param("providerId") providerId: String
): UserEntity?정책 결정:
위 정책 중 적합한 방안을 선택해 반영하거나, 정책이 확정되지 않았다면 반환 타입을 검증 스크립트: rg -n -C3 '\bfindByProviderTypeAndProviderIdIncludingDeleted\s*\('🤖 Prompt for AI AgentsThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain타입 안정성을 위해 파라미터 타입을 ProviderType으로 되돌리는 것을 권장 Repository 메서드에서 ProviderType을 String으로 바꾸면 DB 표현(열 값)이 인프라 경계를 넘어 서비스/도메인 계층까지 전파됩니다. JPA는 Enum 매핑(@Enumerated)을 통해 네이티브 쿼리 파라미터도 적절히 바인딩할 수 있습니다. 가능하다면 ProviderType을 그대로 유지하세요. 아래와 같이 메서드 시그니처를 되돌리고, 구현부에서도 먼저 UserEntity의 providerType 필드가 적용 diff (본 파일 내 변경): - fun findByProviderTypeAndProviderIdIncludingDeleted(
- @Param("providerType") providerType: String,
- @Param("providerId") providerId: String
- ): UserEntity?
+ fun findByProviderTypeAndProviderIdIncludingDeleted(
+ @Param("providerType") providerType: ProviderType,
+ @Param("providerId") providerId: String
+ ): UserEntity?그리고 호출부(UserRepositoryImpl.kt)의 해당 라인도 같이 수정해야 합니다(해당 파일 코멘트 참고). 🏁 Script executed: #!/bin/bash
# UserEntity 선언과 providerType 매핑을 확인
rg -n -C3 'class\s+UserEntity\b'
rg -n -C3 'providerType\b'
rg -n -C3 '@Enumerated|@Column|EnumType'Length of output: 52761 ProviderType Enum 사용으로 파라미터 타입 복원 필요 UserEntity.providerType가 • infra/src/main/kotlin/org/yapp/infra/user/repository/JpaUserRepository.kt --- a/infra/src/main/kotlin/org/yapp/infra/user/repository/JpaUserRepository.kt
+++ b/infra/src/main/kotlin/org/yapp/infra/user/repository/JpaUserRepository.kt
@@ -23,7 +23,7 @@ interface JpaUserRepository : JpaRepository<UserEntity, UUID> {
@Query(
value = "SELECT * FROM users u WHERE u.provider_type = :providerType AND u.provider_id = :providerId",
nativeQuery = true
)
- fun findByProviderTypeAndProviderIdIncludingDeleted(
- @Param("providerType") providerType: String,
+ fun findByProviderTypeAndProviderIdIncludingDeleted(
+ @Param("providerType") providerType: ProviderType,
@Param("providerId") providerId: String
): UserEntity?--- a/infra/src/main/kotlin/org/yapp/infra/user/repository/impl/UserRepositoryImpl.kt
+++ b/infra/src/main/kotlin/org/yapp/infra/user/repository/impl/UserRepositoryImpl.kt
@@ -39,7 +39,7 @@ class UserRepositoryImpl(
override fun findByProviderTypeAndProviderIdIncludingDeleted(
providerType: ProviderType,
providerId: String
): User? {
- return jpaUserRepository.findByProviderTypeAndProviderIdIncludingDeleted(providerType.name, providerId)
+ return jpaUserRepository.findByProviderTypeAndProviderIdIncludingDeleted(providerType, providerId)
?.toDomain()
}🤖 Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,7 +39,7 @@ class UserRepositoryImpl( | |
| providerType: ProviderType, | ||
| providerId: String | ||
| ): User? { | ||
| return jpaUserRepository.findByProviderTypeAndProviderIdIncludingDeleted(providerType, providerId)?.toDomain() | ||
| return jpaUserRepository.findByProviderTypeAndProviderIdIncludingDeleted(providerType.name, providerId)?.toDomain() | ||
|
||
| } | ||
|
|
||
| override fun deleteById(userId: UUID) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.