Error

[Error] 특정 엔티티 삭제 시, 연관관계 엔티티 함께 삭제하기

Ynghan 2024. 3. 5. 19:38

※ 외부 블로그를 참고하여 공부를 목적으로 작성한 글입니다.


진행중인 스프링 프로젝트에서 특정 엔티티를 삭제하려 했지만, 다음과 같은 에러가 나타났다.

java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`news_feed`.`comment`, CONSTRAINT `FKs1slvnkuemjsq2kj4h3vhx7i1` FOREIGN KEY (`post_id`) REFERENCES `post` (`post_id`))
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:118) ~[mysql-connector-j-8.3.0.jar:8.3.0]

해당 에러는 외래 키 제약 조건에 의해 post 테이블의 레코드를 삭제하려 했지만, 해당 레코드가 참조하는 comment 테이블의 레코드가 존재하기 때문에 삭제를 실패했다는 내용이다.
해당 엔티티를 삭제하면, 외래키로 참조하는 엔티티의 부모 엔티티가 존재하지 않게 되어 외래키 무결성을 위배하는 것이다.

이를 해결하려면 삭제하려는 엔티티의 자식 엔티티를 모두 삭제한 후에 해당 엔티티를 삭제해야 한다. 

해결 방법은 2가지가 있다.

1. orphanRemoval = true 설정

@Entity
public class Post extends Timestamped {

	...

    @OneToMany(mappedBy = "post", orphanRemoval = true)
    private List<Comment> comments = new ArrayList<>();

	...

}

이러한 방식은 Post 엔티티를 삭제할 때, 연관관계의 Comment 엔티티 또한 삭제한다.

자식 엔티티를 먼저 삭제하고 부모 엔티티를 삭제하기 때문에 에러가 발생하지 않는다.

 

2. 영속성 전이

@Entity
public class Post extends Timestamped {

	...

    @OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE)
    private List<Comment> comments = new ArrayList<>();
	...

}

cascade = CascadeType.REMOVE를 추가하면 Post를 삭제할 시 Comment도 함께 삭제할 수 있다.

 

orphanRemoval = true 와 CascadeType.REMOVE 의 차이

전자는 연관된 엔티티 사이의 참조가 끊길 때 삭제된다. 후자는 부모 엔티티를 삭제하면 자식 엔티티가 삭제된다.

 

외부 블로그 참조

https://khdscor.tistory.com/18

'Error' 카테고리의 다른 글

[Mac OS] Port 8080 was already in use. 에러  (1) 2024.04.22