프로젝트/선착순 쿠폰 발급 시스템
Kotlin JPA Update Query 작성하기
Junuuu
2023. 5. 28. 00:01
반응형
UserJpaRepositry
@Repository
interface UserJpaRepository : JpaRepository<UserJpaEntity, String>{
@Modifying
@Query("update UserJpaEntity u set u.representationMobileNumber = :mobileNumber where u.userId = :userId")
fun updateMobileNumber(mobileNumber: String, userId: String): Int
}
@Modifying과 @Query를 사용하여 update쿼리를 작성해 주었습니다.
userId와 mobileNumber를 인자로 받아 userId가 동일한 row의 representationMobileNumber를 변경해 주는 역할을 수행합니다.
Int는 update 되는 row의 수를 반환합니다.
Application Layer에서 구현
override fun updateRepresentationMobileNumber(mobileNumber: String, userId: String): String {
val updatedRowCount = userJpaRepository.updateMobileNumber(mobileNumber, userId)
if (updatedRowCount == 0) {
throw NoSuchElementException("userId가 존재하지 않습니다")
}
return mobileNumber
}
실행시켜서 updatedRowCount =0이라면 update가 일어나지 않음을 의미하고 userId를 조회하지 못한 것으로 예외를 발생시켰습니다.
0이 아니라면 업데이트가 일어났음을 의미하니 변경된 mobileNumber를 그대로 반환합니다.
회원이 없는 경우 테스트
@Test
fun `존재하지 않는 회원을 update하면 NoSuchElementException이 발생한다`() {
//given
val userId = "myUserId"
//when & then
assertThrows(NoSuchElementException::class.java) {
userPersistenceAdapter.updateRepresentationMobileNumber(
mobileNumber = "01047970063",
userId = userId
)
}
}
회원이 존재하는 경우 테스트
@Test
fun `존재하는 회원의 대표번호를 update하면 정상적으로 update 된다`() {
//given
val userId = "myUserId"
val userInfo = User.testFixture(
userId = userId,
representationMobileNumber = "01047970063",
)
userPersistenceAdapter.signUp(userInfo)
//when
val updatedRepresentationMobileNumber = userPersistenceAdapter.updateRepresentationMobileNumber(
mobileNumber = "01011112222",
userId = userId
)
//then
entityManager.clear() //클리어를 해주지 않으면 update 쿼리에 의해 db만 변경되고 1차 캐시된 값을 그대로 이용하여 테스트에 실패한다
val user = userJpaRepository.findById(userId).orElseThrow()
assertEquals(user.representationMobileNumber, "01011112222")
assertEquals(updatedRepresentationMobileNumber, "01011112222")
}
given절에서 signUp을 통해 회원가입을 수행시키면 유저의 정보가 테이블에 저장됩니다.
when절에서 updateRepresentationMobileNumber를 수행시키면 update Query가 날아가게 됩니다.
then절에서는 entityManager를 한번 clear 해주어야 합니다.
그렇지 않으면 1차 캐시 된 값을 그대로 이용하게 되어 테스트에 실패합니다.