티스토리 뷰
개요
- Spring Boot, JPA 환경에서 개발자를 당황시키는
AssertionFailure
예외가 발생하는 이유와 해결책을 정리하였다.
org.hibernate.AssertionFailure: null id in com.jsonobject.domain.Foo entry (don't flush the Session after an exception occurs)
AssertionFailure 예외가 발생하는 이유
AssertionFailure
예외를 발생시킨 지점은 실제 범인이 아닐 가능성이 높다. 같은 트랜잭션(세션) 범위 내에서 앞서 실행된 어떤 쿼리가 영향을 미쳤을 확률이 높다.AssertionFailure
예외는@Transactional
이 명시된 세션 내의 복수개의 쿼리가 연속적으로 실행되는 상황에서 중간에 실행된 특정 쿼리로 인해 발생한다. Hibernate는 성능 향상을 위해 트랜잭션의 최종 커밋 시점까지 INSERT, UPDATE, DELETE를 최대한 미루다가 모아서 실행하는데 이 것이 개발자의 의도와 다른 결과를 유발하는 경우가 있고, AssertionFailure 예외도 이러한 대표적인 사례에 속한다.- 내가 반복적으로 경험했던 원인은 한 세션 내에서 FooRepository#save를 실행한 결과가 데이터 무결성 조건에 위배되어
org.springframework.dao.DataIntegrityViolationException
예외가 발생했던 경우이다. 예외 처리를 적절히 수행했더라도 최종적으로 해당 엔티티와 관계가 연결된 다른 엔티티에 대해 BarRepository#findXXX를 실행할 때 뒤늦게org.hibernate.AssertionFailure
예외가 발생했던 것이다. 실제 실행이 실패되어 저장된 id가 획득되지 않은 채로 지나갔고, 같은 세션 내의 해당 Foo 엔티티를 관계로 참조하는 다른 Bar 엔티티를 조회하는 시점에 예외가 발생한 것이다.
해결책
java.sql.SQLIntegrityConstraintViolationException
예외가 발생하는 것을 기다리지 말고, 실행에 앞서 적극적으로 데이터가 중복되는 엔티티의 존재 여부를 검사하고 있다면 삭제하는 로직을 추가한다. 그리고, 데이터 무결성을 위해 삭제와 생성을 같은 트랜잭션 범위로 묶는다. (어떤 이유로 인해 삭제만 되고 생성은 안되는 상황을 예방하는 것이 목적이다.)
참고 글
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- JHipster
- 평속
- 구동계
- maven
- Spring MVC 3
- graylog
- 로드 바이크
- kotlin
- Tomcat
- jsp
- chrome
- Kendo UI
- node.js
- DynamoDB
- 알뜰폰
- CentOS
- Kendo UI Web Grid
- MySQL
- 로드바이크
- jstl
- Spring Boot
- java
- jpa
- 태그를 입력해 주세요.
- 자전거
- Eclipse
- bootstrap
- Docker
- JavaScript
- spring
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함