회원 탈퇴 한 이용자의 이메일과 같은 이메일로 회원 가입을 시도하자 404 Bad Request가 아닌 500 Internal Server Error 발생했습니다.
회원 가입 할 이메일의 중복 체크를 담당하는 메서드는 Jpa Repository의 exists
로, 회원탈퇴는 soft delete로 이뤄지기 때문에 db에 남아있는 탈퇴 이용자의 이메일도 잡아주기를 기대하였으나 500 발생했습니다.
userRepository.existsByEmail(email)
Duplicate entry ‘deletedEmail@gmail.com’
이라고 출력됨@SQLRestriction("deleted = false")
을 User Entity에 걸어놓았기 때문에 exists
메서드를 돌릴 때 repository 에서 deleted=true
인 데이터에 접근할 때@SQLRestriction
과 충돌하여 서버 에러가 난다고 보았습니다.userRepository.existsByEmail(email)
부분에 중단점을 걸고 디버깅을 돌리자 이메일 중복 체크를 하는 부분은 그대로 넘어가고 유저 정보를 save
해서 저장할 때 오류가 잡히는 것을 확인하였습니다.existsByEmail
을 넘어가고 아래의 encode
메서드를 통해 비밀번호가 제대로 encode 된 것을 스레드 및 변수 창에서 확인할 수 있습니다.@SQLRestriction
과 충돌이 난 것이 아니라 이메일 중복검사에서는 중복이 아니라고 판단 내려진 채로 save
메서드에서 유저 정보를 저장하다가 User Entity의 email 필드에 걸어놓은 unique
속성때문에 500 에러가 난 것이었습니다. ⇒ @SQLRestriction
로 제한을 걸어두면 jpa Repository의 exists
메서드로도 접근이 되지 않습니다.repository에서 "deleted = true"
인 데이터에 접근하지 못하고 있기 때문에
@SQLRestriction
에 걸리지 않고 db에 남아있는 탈퇴 이용자의 데이터에 접근할 방법을 모색하였습니다.
@Query
를 사용하여 직접 query문을 작성하여 데이터베이스에 접근하기로 하였습니다.
JPQL
을 사용하는 방법과 Native Query
를 사용하는 방법이 있는데 JPQL
은 아직 배우지 않았기때문에 Native Query
로 작성했습니다.
email이 request에 넣은 이메일과 같은 함수를 찾아 수를 세고 (Count), 이 값이 0보다 클 경우 중복이라고 판단했습니다.
@Query(value = "SELECT *COUNT*(***) FROM user WHERE email = ?1", nativeQuery = *true*)
Soft Delete 방식으로 유저데이터를 삭제하고 repository에서 유저를 조회해야하는 모든 기능에 ‘delete=false ‘인 조건을 추가하고 검색하는 번거로움을 피하기 위해 @SQLRestriction
을 사용하여 Entity 차원에서 걸러주었습니다.
그러나 Entity를 거쳐 db에 접근하는 Jpa Repository의 메서드를 사용할 경우 이 @SQLRestriction
때문에 조건이 충족하지 않는(탈퇴한 이용자) 데이터에는 접근할 수 없었습니다.
따라서 직접 @Query 어노테이션을 사용해 Native Query 문을 작성해 soft delete한 데이터에 접근하여야 했습니다.