티스토리 뷰

이전 글: https://gojs.tistory.com/58

 

컬렉션과 부가 기능

JPA는 Java에서 기본으로 제공하는 Collection, Set, List, Map 등을 지원한다. @Entitypublic class Team { @Id private String id; @OneToMany @JoinColumn private Collection members = new ArrayList(); ...}System.out.println("before persist: " +

gojs.tistory.com

 

JPA의 표준 예외는 javax.persistence.PersistenceException의 자식 클래스이다.

이 PersistenceException은 RuntimeException의 자식 클래스로 unchecked exception이다.

 

이와 같은 JPA 표준 예외는 크게 두 가지로 구분할 수 있다.

1. 트랜잭션 롤백을 표시하는 예외

2. 트랜잭션 롤백을 표시하지 않는 예외

 

트랜잭션 롤백을 표시하는 예외

예외 설명
javax.persistence.EntityExistsException persist() 호출 시 이미 같은 엔티티가 있으면 발생
javax.persistence.EntityNotFoundException getReference(), refresh(), lock() 등을 호출 시 엔티티가 존재하지 않으면 발생
javax.persistence.OptimisticLockException 낙관적 락 충돌 시 발생
javax.persistence.PessimisticLockException 비관적 락 충돌 시 발생
javax.persistence.RollbackException commit() 실패 시 발생
javax.persistence.TransactionRequiredException 트랜잭션이 필요한데 트랜잭션이 없으면 발생

 

트랜잭션 롤백을 표시하지 않는 예외

예외 설명
javax.persistence.NoResultException getSingleResult() 호출 시 결과가 없는 경우 발생
javax.persistence.NonUniqueResultException getSingleResult() 호출 시 결과가 많은 경우 발생
javax.persistence.LockTimeoutException 비관적 락의 시간초과 시 발생
javax.persistence.QueryTimeoutException 쿼리 실행 시간 초과 시 발생

 

스프링의 JPA 예외 변환

스프링은 시스템이 특정 기술에 의존되지 않도록 데이터 접근 계층에 대한 예외를 추상화해서 제공한다.

따라서 아래의 표와 같이 JPA 표준 예외가 Spring 예외로 변환된다.

JPA 표준 예외 Spring 예외
javax.persistence.PersistenceException org.springframework.orm.jpa.JpaSystemException
javax.persistence.NoResultException org.springframework.orm.jpa.EmptyResultDataAccessException
javax.persistence.NonUniqueResultException org.springframework.orm.jpa.IncorrectResultSizeDataAccessException
javax.persistence.LockTimeoutException org.springframework.orm.jpa.CannotAcquireLockException
javax.persistence.QueryTimeoutException org.springframework.orm.jpa.QueryTimeoutException
javax.persistence.EntityExistsException org.springframework.orm.jpa.DataIntegrityViolationException
javax.persistence.EntityNotFoundException org.springframework.orm.jpa.JpaObjectRetrievalFailureException
javax.persistence.OptimisticLockException org.springframework.orm.jpa.JpaOptimisticLockingFailureException
javax.persistence.PessimisticLockException org.springframework.orm.jpa.PessimisticLockingFailureException
javax.persistence.TransactionRequiredException org.springframework.orm.jpa.InvalidDataAccessApiUsageException
javax.persistence.RollbackException org.springframework.orm.jpa.TransactionSystemException
java.lang.IllegalStateException org.springframework.dao.InvalidDataAccessApiUsageException
java.lang.IllegalArgumentException org.springframework.dao.InvalidDataAccessApiUsageException

 

스프링 애플리케이션에 JPA 예외 변환기 등록

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
}

위의 코드와 같이 PersistenceExceptionTranslationPostProcessor 인스턴스를 스프링 빈으로 등록한다.

@Repository가 적용된 클래스에 AOP를 적용시켜 발생하는 JPA 예외를 스프링 예외로 변환시킨다.

 

@Repository
public class NoResultExceptionTestRepository {
	
    @PersistenceContext
    EntityManager em;
    
    public Member findMember() {
        return em
            .createQuery("select m from Member m", Member.class)
            .getSingleResult();
    }
}

위 코드에서 findMember() 메서드의 결과가 없는 경우 JPA 예외인 NoResultException이 먼저 발생하고 이를 PersistenceExceptionTranslationPostProcessor가 Spring 예외인 EmptyResultDataAccessException 예외로 변환하게 된다.

 

트랜잭션 롤백 시 주의사항

트랜잭션을 롤백하게되면 데이터베이스의 반영 사항을 롤백하지만 Java 오브젝트를 롤백하지 않는다.

따라서 영속성 컨텍스트를 안전하게 사용하기 위해 새로 만들거나 clear()를 호출해야한다.

트랜잭션당 영속성 컨텍스트 전략은 트랜잭션을 롤백하는 시점에 영속성 컨텍스트를 종료하기 때문에 문제가 없다.

Spring OSIV처럼 영속성 컨텍스트 범위를 트랜잭션 범위보다 넓게 쓰는 경우에 문제가 발생할 수 있다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함