영속성 전이는 JPA에서 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 사용합니다.
예를 들어, Parent-Child
관계에서 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장되게 하거나, 부모 엔티티를 삭제할 때 자식 엔티티도 함께 삭제하고 싶을 때 사용합니다.
cascade 옵션은 JPA에서 @ManyToOne
과 @OneToMany
관계에서 사용할 수 있습니다.
양방향 일대다 관계인 게시글과 댓글로 예시를 보여드리겠습니다.
@Entity
public class Article { // 게시글 엔티티
@Id @GeneratedValue
@Column(name = "article_id")
private Long id;
private String title;
private String content;
@OneToMany(mappedBy = "article")
private List<Comment> comments = new ArrayList<>();
//== 연관관계 메서드 ==//
public void addComment(Comment comment) {
comments.add(comment);
comment.belongToArticle(this);
}
}
@Entity
public class Comment { // 댓글 엔티티
@Id @GeneratedValue
@Column(name = "comment_id")
private Long id;
private String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "article_id")
private Article article;
//== 연관관계 메서드 ==//
public void belongToArticle(Article article) {
this.article = article;
}
}
@Transactional
@Service @RequiredArgsConstructor
public class ArticleRegisterService {
private final ArticleRepository articleRepository;
//** 예시입니다 **//
public Long addArticle() {
Article article = new Article();
article.setTitle("예시 제목입니다.");
article.setContent("예시 내용입니다~~");
Comment comment1 = new Comment();
comment1.setContent("첫 댓글입니다");
article.addComment(comment1);
Comment comment2 = new Comment();
comment2.setContent("두 번째 댓글입니다");
article.addComment(comment2);
return articleRepository.save(article).getId();
}
}
위와 같은 상태에서 addArticle()
메서드가 실행된다면 엔티티들의 테이블은 다음과 같습니다.
article_id | title | content |
---|---|---|
1 | 예시 제목입니다. | 예시 내용입니다~~ |
comment_id | content | article_id |
---|---|---|
보이시는 것과 같이 Comment
에 대한 데이터는 테이블에 저장되지 않았습니다.
하지만, cascade 옵션을 사용한다면!!
@OneToMany(mappedBy = "article", cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();
다음과 같이 테이블에 변화가 생깁니다.
article_id | title | content |
---|---|---|
1 | 예시 제목입니다. | 예시 내용입니다~~ |
comment_id | content | article_id |
---|---|---|
2 | 첫 댓글입니다 | 1 |
3 | 두 번째 댓글입니다 | 1 |
어떻게 이런 일이 가능할까요??
👉 그것은 바로 cascade를 통해 Article
엔티티를 영속 상태로 만들 때 연관된 Comment
엔티티도 함께 영속 상태로 만들고 데이터를 저장하기 때문입니다.
그렇다면, cascade 옵션의 종류를 무엇이 있을까요??
CascadeType.ALL
: 모든 Cascade 옵션을 적용합니다.CascadeType.PERSIST
: 엔티티를 영속화할 때, 연관된 엔티티도 함께 영속화합니다.CascadeType.REMOVE
: 엔티티를 제거할 때, 연관된 엔티티도 함께 제거합니다.CascadeType.MERGE
: 엔티티 상태를 병합할 때, 연관된 엔티티도 함께 병합합니다.CascadeType.REFRESH
: 부모 엔티티를 Refresh하면, 연관된 엔티티도 함께 Refresh됩니다.CascadeType.DETACH
: 부모 엔티티를 Detach하면, 연관된 엔티티도 함께 Detach됩니다.대부분의 경우, CascadeType.ALL
을 사용하지만, 상황과 목적에 맞게 사용하시면 될 것 같습니다.
영속성 전이는 연관관계를 매핑하는 것과는 아무 관련이 없습니다.
그저 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 등의 편리함을 제공할 뿐입니다.
또한, 연관관계에서 단 하나의 부모에 종속하는 경우에만 사용하는 것이 좋습니다.
김영한님의 자바 ORM 표준 JPA 프로그래밍 강의와 스스로 공부한 내용을 토대로 제작한 글입니다.
잘못된 내용이나 오타가 있다면 댓글로 알려주시면 감사하겠습니다!