JPA의 경우 예외가 발생하면 JPA예외가 발생하게 된다.
EntityManager
는 순수한 JPA 기술이고, 스프링과는 관계가 없다.
따라서 엔티티 매니저는 예외가 발생하면 JPA 관련 예외를 발생시킨다.
JPA는 PersistenceException
과 그 하위 예외를 발생시킨다.
추가로 JPA는 IllegalStateException
, IllegalArgumentException
을 발생시킬 수 있다.
즉, 만약에 코드에 @Repository가 없다면 반드시 위 3개의 예외 중 하나를 반환한다는 것이다.
당연하다 앞서 말 했듯 JPA는 스프링이 아니고 Hibernate 이기 때문이다.
그렇다면 JPA 예외를 스프링 예외 추상화( DataAccessException )로 어떻게 변환할 수 있을까?
비밀은 바로 @Repository 에 있다.
결과적으로 리포지토리에 @Repository 애노테이션만 있으면 스프링이 예외 변환을 처리하는 AOP를 만들어준다.
참고
스프링 부트는 PersistenceExceptionTranslationPostProcessor
를 자동으로 등록하는데, 여기에서 @Repository 를 AOP 프록시로 만드는 어드바이저가 등록된다.
참고
복잡한 과정을 거쳐서 실제 예외를 변환하는데, 실제 JPA 예외를 변환하는 코드는 EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible()
이다.