JPA 예외 변환

강정우·2024년 1월 25일
0

JPA

목록 보기
4/12

JPA 예외 변환

JPA의 경우 예외가 발생하면 JPA예외가 발생하게 된다.

EntityManager 는 순수한 JPA 기술이고, 스프링과는 관계가 없다.
따라서 엔티티 매니저는 예외가 발생하면 JPA 관련 예외를 발생시킨다.

JPA는 PersistenceException 과 그 하위 예외를 발생시킨다.
추가로 JPA는 IllegalStateException , IllegalArgumentException 을 발생시킬 수 있다.

즉, 만약에 코드에 @Repository가 없다면 반드시 위 3개의 예외 중 하나를 반환한다는 것이다.
당연하다 앞서 말 했듯 JPA는 스프링이 아니고 Hibernate 이기 때문이다.

그렇다면 JPA 예외를 스프링 예외 추상화( DataAccessException )로 어떻게 변환할 수 있을까?
비밀은 바로 @Repository 에 있다.

  • @Repository의 기능
  1. @Repository 가 붙은 클래스는 컴포넌트 스캔의 대상이 된다.
  2. @Repository 가 붙은 클래스는 예외 변환 AOP의 적용 대상이 된다.
    • 스프링과 JPA를 함께 사용하는 경우 스프링은 JPA 예외 변환기
      ( PersistenceExceptionTranslator )를 등록한다.
    • 예외 변환 AOP 프록시는 JPA 관련 예외가 발생하면 JPA 예외 변환기를 통해 발생한 예외를 스프링 데이터 접근 예외로 변환한다.
      위 사진이 아래 예외 변화 AOP Proxy의 결과문 CGLIB이다.

결과적으로 리포지토리에 @Repository 애노테이션만 있으면 스프링이 예외 변환을 처리하는 AOP를 만들어준다.

  • 참고
    스프링 부트는 PersistenceExceptionTranslationPostProcessor 를 자동으로 등록하는데, 여기에서 @Repository 를 AOP 프록시로 만드는 어드바이저가 등록된다.

  • 참고
    복잡한 과정을 거쳐서 실제 예외를 변환하는데, 실제 JPA 예외를 변환하는 코드는 EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible() 이다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글