중간테이블 데이터로 인한 데이터 삭제 오류
✅ 현재 상황
- OptionGroup 과 Option 을 중간테이블을 두어 일대다, 다대일 관계로 풀어내었다.
- OptionGroup 에서 Option 에 대한 정보를 갖고 있을 때(중간테이블), OptionGroup 을 삭제할 때 에러가 발생한다.
🤔 실제 발생한 에러 정리
org.springframework.dao.DataIntegrityViolationException: could not execute statement;
SQL [n/a]; constraint
- Foreign Key로 다른 테이블로부터 참조를 당하고 있는 계정 테이블의 데이터를 삭제하려고 하니 발생하는 문제였다. 참조를 하는 테이블(중간테이블)부터 먼저 데이터를 deleteAll()해주고, 계정 테이블을 deleteAll()하면 간단히 해결되는 문제였다.
- 실제로, OptionAndOptionGroup 쪽의 데이터를 먼저 삭제해주고(다대일 에서 다쪽)
→ 다 쪽에서 외래키를 갖고 있기 때문, 외래키로 참조하는 행위를 먼저 끊어준다.
그 후 Option 부분 삭제해주니 오류 없이 작동했다.
🤔 @Transactional 이 없어서 발생하는 에러
data jpa 를 통해 delete 메서드 실행했는데, 자꾸 똑같은 오류가 발생.
TransactionRequiredException: No EntityManager with actual transaction available for current thread
- cannot reliably process 'remove' call.
또 에러가 발생했다…
🤔 옵션그룹이 삭제가 안되는 현상.
- 메뉴에서 옵션그룹을 참조하고 있어서, (외래키를 갖고 있기 때문에)
외래키 정보에 대한 PK 원본 데이터를 삭제하려고 하니 발생하는 에러.
- 이것 역시 정확히는 MenuAndOptionGroup 이라는 중간테이블에서 OptionGroup 에 대한 정보를 FK로 들고 있었기 때문에 발생하는 오류였다.
could not execute statement; SQL [n/a]; constraint [null];
nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
결론
- 다대다 관계를 일대다, 다대일로 풀어서 중간테이블에서 각 테이블을 외래키로 참조하기 때문에 특정 엔티티 정보에 대해 삭제를 수행할 때,
ConstraintViolationException
이 자주 발생한다.
- 삭제 메서드를 구현할 때는, 중간테이블에서 외래키를 참조하는 내역들을 반드시 삭제해주자.
- data jpa에서 Delete 메서드를 사용할 때, TransactionRequiredException 이 발생하면, Service에 @Transactional 을 통해 한 트랜잭션 내에서 관리하도록 하자.