JPA 표준 예외들은 javax.persistence.PersistenceException의 자식 클래스다. 이 예외 클래스는 RuntimeException의 자식이다.
따라서 JPA 예외는 모두 언체크 예외다.
JPA 표준 예외는 크게 2가지로 나뉜다. - 트랜잭션 롤백을 표시하는 예외 - 트랜잭션 롤백을 표시하지 않는 예외
트랜잭션 롤백을 표시하는 예외는 심각한 예외이므로 복구해선 안 된다. 이 예외가 발생하면 트랜잭션을 강제로 커밋해도 트랜잭션이 커밋되지 않고 대신 javax.persistence.Rollbak 예외가 발생한다.
반면 트랜잭션 롤백을 표시하지 않는 예외는 심각한 예외가 아니다.
따라서 개발자가 트랜잭션을 커밋할지 롤백할지를 판단하면 된다.
| 트랜잭션 롤백을 표시하는 예외 | 설명 |
|---|---|
| EntityExistsException | EntityManager.persist(..) 호출 시 이미 같은 엔티티가 있으면 발생 |
| EntityNotFoundException | EntityManager.getReference(..)를 호출했는데 실제 사용 시 엔티티가 존재하지 않으면 발생.refresh(..), lock(..)에서도 발생 |
| OptimisticLockException | 낙관적 락 충돌 시 발생 |
| PerssimisticLockException | 비관적 락 충돌 시 발생 |
| RollbackException | EntityTransaction.commit() 실패 시 발생롤백이 표시되어 있는 트랜잭션 커밋 시에도 발생 |
| TransactionRequiredException | 트랜잭션이 필요할 때 트랜잭션이 없으면 발생트랜잭션 없이 엔티티를 변경할 때 주로 발생 |
| 트랜잭션 롤백을 표시하지 않는 예외 | 설명 |
|---|---|
| NoResultException | Query.getSingleResult() 호출 시 결과가 하나도 없을 때 발생 |
| NonUniqueResultException | Query.getSingleResult() 호출 시 결과가 둘 이상일 때 발생 |
| LockTimeoutException | 비관적 락에서 시간 초과 시 발생 |
| QueryTimeoutException | 쿼리 실행 시간 초과 시 발생 |
서비스 계층에서 데이터 접근 계층의 구현 기술에 직접 의존하는 것은 좋은 설계라 할 수 없다.
예외도 마찬가지다. 예를 들어 서비스 계층에서 JPA의 예외를 직접 사용하면 JPA에 의존하게 된다.
스프링 프레임워크는 이런 문제를 해결하려고 데이터 접근 계층에 대한 예외를 추상화해서 개발자에게 제공한다.

JPA 예외를 스프링 예외로 변경
추가로 JPA 표준 명세상 발생할 수 있는 두 예외도 추상화 해서 제공한다.
