프로젝트/선착순 쿠폰 발급 시스템

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차 캐시 된 값을 그대로 이용하게 되어 테스트에 실패합니다.