부트캠프 과제 中 트러블슈팅 과정 작성 글
일정 관리 앱 서버 ver.2
1. 문제
Spring Data Jpa 실습 중 [회원가입]을 시도하는 부분에서 email을 Unique
로 지정해 가입을 하려고 했다.
만약 같은 email로 가입을 시도하면, 이미 존재하는 email이라는 메세지를 전달하려고 했지만 그 예외가 잡히지 않았다.
2. 원인
java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '_@email' for key 'user.UKob8kqyqqgmefl0aco34akdtpe'
분명 같은 email로 가입을 시도하면 SQLIntegrityConstraintViolationException
예외가 뜬다.
가입 시도를 위해 jpa로 save()
를 진행하는 부분을 try
에 넣고, catch(SQLIntegrityConstraintViolationException)
을 하려고 했지만 계속 예외를 던지지 않아 잡힐 수 없다는 경고가 떴다.
3. 해결 방법
어떤 걸 사용하느냐에 따라서 던져지는 예외가 달라진다.
JDBC는 키가 중복되면 DuplicateKeyException
를 발생시키고, Hibernate는 ConstraintViolationException
을 발생시킨다. 스프링은 DataIntegrityViolationException
으로 변환한다.
스프링 환경에서 Spring Data Jpa를 이용하고 있어, 발생하는 예외는 SQLIntegrityConstraintViolationException
이지만, 실제로 스프링은 DataIntegrityViolationException
으로 래핑해서 던지고 있다.
SQLException
도 SQLIntegrityConstraintViolationException
도 아닌 DataIntegrityViolationException
을 catch
해야만 중복 키 예외가 잡히는 것이었다.
try{
// 예외가 발생할 수 있는 부분
// 중복 키가 들어갈 수 있음
User save = userRepository.save(getUser);
savedUser = save;
} catch (DataIntegrityViolationException e){
throw new ValidException(ExceptionCode.DUPLICATE_USER_EMAIL);
}
if를 이용해 비교하며 같은 email이 있으면 예외를 직접 발생시킬 수 있다.
개발자가 직접 Custom Exception을 만들어도 된다.
굳이 비교하는 로직을 넣지 않고도, 스프링이 알아서 예외를 던질 수 있으니 그 방법을 사용하고 싶어 catch로 잡고 싶었다.
만약 save() 중 키가 중복되는 예외가 발생하면 savedUser=save가 실행되지 않고 예외가 발생해 catch로 잡을 것이다.
4. 결론
상황에 따라서 던져지는 예외가 다르다. JDBC와 Hibernate도 다르고, Spring자체에서 던지는 예외도 다르다.
개발 환경에 맞춰서 발생하는 예외가 어떻게 감싸져서 던져지는지 확인해봐야 한다.
해당 글에서는 중복 키에 대한 예외 처리를 설명하고 있다.
reference
"토비의 스프링3.1 Vol.1 스프링의 이해와 원리", 4.2 예외 전환
'etc > error' 카테고리의 다른 글
[IntelliJ] 프로젝트 생성 중 오류 -No locally installed toolchains (0) | 2025.01.27 |
---|---|
[JS] Uncaught ReferenceError: ... is not defined 오류 해결 방법 (0) | 2024.12.27 |