CASCADE 영속성 상태를 전이해주는 역할이다.
꼭 관계에서 주인이라고 쓸 수 있는 건 아니다.
주인이 아니더라도 쓸 수 있다.
영속성을 전이해주면 편리하겠지만 어딘가 side effect가 생길 것 같은 스멜이 폴폴 난다..🤔
프로젝트나 미션을 할 때, 아직까지는 CASCADE의 필요성을 느낀 적이 없어서 주의사항을 잘 모르겠다!
뭔가 위험할 것 같은데, 구체적으로 왜 그런지 알아보려고 한다.
이름 그대로 REMOVE 상태를 전이해주는 것이다.
뭔가 제일 위험해보여서 요것부터 알아보려고 한다.
양방향 매핑
Article(One) ↔ Comment(Many)
@Entity
public class Article extends BaseEntity {
private String title;
// One에서 Many쪽으로 CASCADE.REMOVE를 달아주었다.
@OneToMany(mappedBy ="article",cascade = CascadeType.REMOVE)
private List<Comment> comments = new ArrayList<>();
protected Article() {
}
public Article(String title) {
this.title = title;
}
public void add(Comment comment) {
this.comments.add(comment);
}
}
@Entity
public class Comment extends BaseEntity {
private String content;
@ManyToOne
private Article article;
protected Comment() {
}
public Comment(String content, Article article) {
this.content = content;
this.article = article;
}
}
@Test
public void cascadeRemoveTest() {
// given : Article(1) - Comment(3)
Article article = new Article("게시글 1");
articleRepository.save(article);
Comment comment1 = new Comment("댓글1", article);
Comment comment2 = new Comment("댓글1", article);
Comment comment3 = new Comment("댓글1", article);
commentRepository.saveAll(Arrays.asList(comment1, comment2, comment3));
Article savedArticle = articleRepository.findById(1L).get();
// when : Article을 지운다.
// Article은 Comment에 CASCADE.REMOVE를 걸었다.
articleRepository.delete(savedArticle);
}
N+1로 삭제한다.
Comment가 100개라면.. 1000개라면!
Hibernate:
delete
from
comment
where
id=?
Hibernate:
delete
from
comment
where
id=?
Hibernate:
delete
from
comment
where
id=?
Hibernate:
delete
from
article
where
id=?
성능 이슈를 내기 쉬운 부분인데 잘 작성해 주셨네요 :)