ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA] 예외 처리
    프로그래밍/JPA 2021. 11. 5. 00:19
    반응형

    이 글은 혼자 학습한 내용을 바탕으로 작성되었습니다.

    틀리거나 잘못된 정보가 있을 수 있습니다.

    댓글로 알려주시면 수정하도록 하겠습니다.


    1. JPA 표준 예외

    • JPA의 표준 예외들은 javax.persistence.PersistenceException의 자식 클래스이며 이 예외 클래스의 부모는 모두 RuntimeException이다. 따라서 JPA는 모두 Uncheck Exception이다.

     

    2. JPA의 예외 종류

    • 트랜잭션 롤백을 표시하는 예외
      심각한 예외로 복구해서는 안되며 예외가 발생하면 트랜잭션을 강제로 커밋하여도 커밋되지 않고 RollbackException이 발생한다.

      예외 설명
      javax.persistence.EntityExstsException persist함수 호출 시 이미 같은 엔티티가 있으면 발생
      javax.persistence.EntityNotFoundException getReference함수 호출하여 프록시를 받아 실제 사용 시 엔티티가 존재하지 않으면 발생
      javax.persistence.OptimisticLockException 낙관적 락 충돌 시 발생
      javax.persistence.PessimisticLockException 비관적 락 충돌 시 발생
      javax.persistence.RollbackException 트랜잭션 커밋 실패 시 발생,
      롤백을 해야 하는 트랜잭션 커밋 시에도 발생
      javax.persistence.TransactionRequiredException 트랜잭션이 필요할 때 트랜잭션이 없으면 발생,
      트랜잭션을 선언하지 않고 엔티티를 수정할 때 주로 발생
    • 트랜잭션 롤백을 표시하지 않는 예외
      심각한 예외가 아니며 개발자가 트랜잭션을 커밋할지 롤백할지를 판단하여 결정하면 된다.

      예외 설명
      javax.persistence.NoResultException getSingleResult함수 호출 시 결과가 없을 때 발생
      javax.persistence.NonUniqueResultException getSingleResult함수 호출 시 결과가 둘 이상인 경우 발생
      javax.persistence.LockTimeoutException 비관적 락에서 시간 초과 시 발생
      javax.persistence.QueryTimeoutException 쿼리 실행 시간 초과 시 발생

    3. 스프링 프레임워크의 JPA 예외 변환

    • 서비스 계층에서 데이터 접근 계층의 구현 기술에 직접 의존하는 것은 좋은 설계가 아니다.

      예외 또한 마찬가지로 서비스 계층에서 JPA의 예외를 직접 사용하면 JPA에 의존하게 되는 것으로 좋은 설계가 아니다.

      스프링 프레임워크는 이러한 문제를 해결하고자 데이터 접근 계층에 대한 예외를 추상화하여 제공한다.

    4. JPA 예외 변환기 적용

    • 스프링 프레임워크가 제공하는 추상화된 예외로 변경된 예외를 받기 위해서는 PersistenceExceptionTranslationPostProcessor를 빈으로 등록하면 된다.

    • PersistenceExceptionTranslationPostProcessor는 Repository 어노테이션이 적용된 곳에서 예외 변환 AOP를 적용해 JPA 예외를 스프링 프레임워크 예외로 추상화해준다.

      만약 예외를 변환하지 않고 그대로 받아보려면 그대로 반환할 JPA 예외 클래스 또는 JPA 예외의 상위 예외 클래스를
      throws 절에 명시하면 된다.

      예를 들어 모든 예외의 부모는 Exception이므로 Exception을 throws 하면 모든 JPA예외를 그대로 전달한다.

    • XML 설정 <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslat ionPostProcessor"/>를 작성하여 빈으로 등록
    • JavaConfig 설정
      위 사진처럼 Configuration클래스를 등록하고 빈으로 등록하면 된다.

    • SpringBoot 1.2 버전 이상부터는 Config설정을 하지 않아도 기본 설정으로 PersistenceExceptionTranslationPostProcessor가 등록됩니다.

    5. 예외 변환기 적용

    Service의 getBeliever함수
    Repository 클래스

    Controller를 통해 Believer Service의 getBeliever함수를 호출하면 Repository 클래스의 getBeliever 함수를 호출한다.

    이미 Believer 테이블에는 여러 명의 Believer가 입력되어 있으므로 getSingleResult는 Exception을 발생시킨다.

    출력된 Exception의 StackTrace이다. 보이는 것과 같이 org.springframework.dao.IncorrectResultSizeDataAccessException이 출력되었다.

     

    Service의 Catch에서 잡은 Exception 객체 내용을 확인하면 스프링 프레임워크 예외 클래스이며 cause를 보면 하위 예외인 JPA의 javax.persistence.NonUniqueResultException이 예외 체인으로 있는 것을 확인할 수 있습니다.

     

     

    throws 절을 통해 Exception을 throw 하는 경우는 모든 JPA Exception이 변환되지 않으므로 javax.persistence.NonUniqueResultException이 출력된다.

    반응형

    '프로그래밍 > JPA' 카테고리의 다른 글

    [JPA] Attribute Converter  (0) 2022.01.12
    [JPA] Dirty Checking(변경 감지)  (0) 2021.12.24
    [JPA] 연관관계의 주인  (0) 2021.10.21
    [JPA] 연관관계  (0) 2021.10.20
    [JPA] Entity 매핑  (0) 2021.10.17

    댓글

Designed by Tistory.