Reference. 자바 ORM 표준 JPA 프로그래밍
책 목차 및 이전 글
더보기
들어가기 전 JPA 특징, Q&A
1. JPA 소개
3. 영속성 관리
4. 엔티티 매핑
4.1 - 4.3 @Entity, @Table, 다양한 매핑
4.4 - 4.5 데이터베이스 스키마 자동 생성, DDL 생성 기능
5. 연관관계 매핑 기초
6. 다양한 연관관계 매핑
7. 고급매핑
8. 프록시와 연관관계 관리
9. 값 타입
9.3~5 값 타입과 불변 객체, 값 비교, 값 타입 컬렉션
10. 객체지향 쿼리 언어
11. 웹 애플리케이션 제작
11.1 프로젝트 환경설정
11.2 도메인 모델과 테이블 설계
11.3 애플리케이션 구현
12. 스프링 데이터 JPA
12.1~3 스프링 데이터 JPA 소개, 공통 인터페이스 기능
12.5~10 명세, 사용자 정의 리포지토리, Web 확장...
13. 웹 애플리케이션과 영속성 관리
14. 컬렉션과 부가기능
15.1.1 JPA 표준 예외 정리
- JPA 표준 예외들은 javax.persistence.PersistenceException의 자식 클래스
- 예외 클래스들은 RuntimeException의 자식이므로 모두 언체크 예외
- JPA 표준 예외는 크게 2가지로 분류
- 트랜잭션 롤백을 표시하는 예외
- 심각한 예외이므로 복구하면 안됌
- 강제로 커밋해도 트랜잭션 커밋되지 않고
RollbackException
예외가 발생
- 트랜잭션 롤백을 표시하지 않는 예외
- 심각한 예외가 아님
- 개발자가 트랜잭션 커밋을할지 롤백할건지 판단
- 트랜잭션 롤백을 표시하는 예외
트랜잭션 롤백을 표시하는 예외
트랜잭션 롤백을 표시하는 예외 | 설명 |
---|---|
javax.persistence.EntityExistsException | EntityManager.persist() 호출시 이미 같은 엔티티가 있으면 발생 |
javax.persistence.EntityNotFoundException | EntityManager.getReference() 호출했는데 실제 엔티티가 존재하지 않으면 발생, refresh(), lock()에서도 발생 |
javax.persistence.OptimisticLockException | 낙관적 락 충돌시 발생 |
javax.persistence.PessimisticLockException | 비관적 락 충돌시 발생 |
javax.persistence.RollbackException | EntityTransaction.commit() 실패 시 발생, 롤백이 표시되어 있는 트랜잭션 커밋 시에도 발생 |
javax.persistence.TransactionRequiredException | 트랜잭션이 필요할 때 트랜잭션이 없으면 발생, 트랜잭션 없이 엔티티를 변경할 때 주로 발생 |
트랜잭션 롤백을 표시하지 않는 예외
트랜잭션 롤백을 표시하지 않는 예외 | 설명 |
---|---|
javax.persistence.NoResultException | Query.getSingleResult() 호출 시 결과가 하나도 없을 때 발생 |
javax.persistence.NonUniqueResultException | Query.getSingleResult() 호출 시 결과가 둘 이상일 때 발생 |
javax.persistence.LockTimeoutException | 비관적 락에서 시간 초과 시 발생 |
javax.persistence.QueryTimeoutException | 쿼리 실행 시간 초과 시 발생 |
15.1.2 스프링 프레임워크의 JPA 예외 반환
- 서비스 계층에서 JPA 예외를 직접 사용하면 JPA 의존하게 되는데 스프링 프레임 워크는 이런 문제를 해결하려고 데이터 접근 계층에 대한 예외를 추상화해서 개발자에게 제공
JPA 에외를 스프링 예외로 변경
JPA 예외 | 스프링 변환 예외 |
---|---|
javax.persistence.PersistenceException | org.springframework.orm.jpa. JpaSystemException |
javax.persistence.NoResultException | org.springframework.dao. EmptyResultDataAccessException |
javax.persistence.NonUniqueResultException | org.springframework.dao.IncorrectResultSize. DataAccessException |
javax.persistence.LockTimeoutException | org.springframework.dao. CannotAcquireLockException |
javax.persistence.QueryTimeoutException | org.springframework.dao. QueryTimeoutException |
javax.persistence.EntityExistsException | org.springframework.dao. DataIntegrityCiolationException |
javax.persistence.EntityNotFoundException | org.springframework.orm.jpa. JpaObjectRetirevalFailureException |
javax.persistence.OptimisticLockException | org.springframework.orm.jpa. JpaOptimistickLockingFailureException |
javax.persistence.PessimisticLockException | org.springframework.dao. PessimisticLockingFailureException |
javax.persistence.TransactionRequiredException | org.springframework.dao. InvalidDataAccessApiUsageException |
javax.persistence.RollbackException | org.springframework.transaction. TransactionSystemException |
- JPA 표준 명세상 발생할 수 있는 두 예외도 추상화해서 제공
JPA 예외를 스프링 예외로 변경 추가
JPA 예외 | 스프링 변환 예외 |
---|---|
java.lang.IllegalStatieException | org.springframework.dao.InvalidDataAccessApiUsageException |
java.lang.IllegalArgumentException | org.springframework.dao.InvalidDataAccessApiUsageException |
15.1.3 스프링 프레임워크에 JPA 예외 변환기 적용
- JPA 예외를 스프링 프레임워크가 제공하는 추상화된 예외로 변경하려면
PersistenceExceptionTranslationPostProcessor
를 스프링 빈으로 등록
- @Repository 어노테이션을 사용한 곳에 예외 변환 AOP를 적용해서 추상한 예외로 변환
- 설정하는 예시
//xml <bean class="org.springframework.dao.annotaion. PersistenceExceptionTranslationPostProcessor" /> //Java Config @Bean public PersistenceExceptionTransactionPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); }
- 예외 변환 예시
@Repository public class NoResultExceptionTestRepository { @PersistenceContext EntityManager em; public Member findMember() { //조회된 데이터 없음 return em.createQuery("select m from Member m", Member.class) .getSingleResult(); } }
- 결과가 없으면
javax.persistence.NoResultException
이 발생
- 예외가
findMember()
메소드를 빠져 나갈 때 등록한 AOP 인터셉터가 동작해 예외를 변환 →org.springframework.dao.EmptyResultDataAccessException
예외로 변환해서 반환
- 예외를 변환하지 않고 그대로 반환하고 싶은 경우 throws 절에 반환할 예외를 직접 명시
java.lang.Exception
을 선언하면 모든 예외의 부모이므로 예외를 변환 안함
... public Member findMember() throws javax.persistence.NoResultException { return em.createQuery("select m from Member m", Member.class) .getSingleResult(); }
- 결과가 없으면
15.1.4 트랜잭션 롤백 시 주의사항
- 트랜잭션을 롤백하는 것은 DB의 반영사항만 롤백하는 것이지 객체까지 복구하지 못함
- 트랜잭션이 롤백된 영속성 컨텍스트를 그대로 사용하는 것은 위험
- 새로운 영속성 컨텍스트를 사용하거나
EntityManger.clear()
를 호출해서 초기화가 필요
- 스프링 프레임워크가 제공하는 기본 전략은 AOP 종료 시점에 트랜잭션을 롤백하면서 영속성 컨텍스트도 함께 종료하므로 문제를 방지
- 문제는 OSIV처럼 영속성 컨텍스트의 범위를 트랜잭션 범위보다 넓게 사용할 때 발생
- 여러 트랜잭션이 하나의 영속성 컨텍스트를 사용하므로 발생하는 문제
- 스프링 프레임워크는 영속성 컨텍스트의 범위를 트랜잭션의 범위보다 넓게 설정하면 트랜잭션 롤백시 영속성 컨텍스트를 초기화(
EntityManger.clear()
)해서 문제를 예방
'개발서적 > 자바 ORM 표준 JPA' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍] 15.3 프록시 심화 주제 (0) | 2021.10.25 |
---|---|
[자바 ORM 표준 JPA 프로그래밍] 15.2 엔티티 비교 (0) | 2021.10.25 |
[자바 ORM 표준 JPA 프로그래밍] 14.4 엔티티 그래프 (0) | 2021.10.25 |
[자바 ORM 표준 JPA 프로그래밍] 14.3 리스너 (0) | 2021.10.25 |
[자바 ORM 표준 JPA 프로그래밍] 14.2 @Converter (0) | 2021.10.25 |