엔티티의 상태 변화를 전파시키는 옵션입니다.
@ManyToOne, @OneToMany, @OneToOne 을 통해 연관관계를 맺은 엔티티 사이의 상태 변화를 전파시킵니다.
Book book = new Book();
entityManger.persist(book);
entityManger.remove(book);
entityManger.detach(book);
Cascade 옵션은 이러한 상태 변화를 연관된 엔티티에 전이시키는 옵션입니다.
Cascade 옵션을 알아보기 위해 게시글(Post) 와 댓글(Comment)를 예시로 들어보겠습니다.
Post 클래스
@Entity
public class Post {
@Id
@GeneratedValue
@Column(name = "POST_ID")
private Long id;
@Column(name = "TITLE")
private String title;
@OneToMany(mappedBy = "post")
private List<Comment> commentList = new ArrayList<>();
// constructor, getter, setter, ...
}
Comment 클래스
@Entity
public class Comment {
@Id
@GeneratedValue
@COLUMN(name = "COMMENT_ID")
private Long id;
@Column(name = "CONTENT")
private String content;
@ManyToOne
@JoinColumn(name = "POST_ID")
private Post post;
// constructor, getter, setter, ...
}
하위 엔티티까지 영속성을 전달합니다.
Post Entity를 저장하면 하위 엔티티인 Comment Entity도 저장합니다.
@Test
public void 부모엔티티_저장시_자식_엔티티도_함께_저장() {
Post post = new Post();
post.setTitle("게시글 제목");
Comment comment1 = new Comment();
comment1.setContent("댓글 1");
Comment comment2 = new Comment();
comment2.setContent("댓글 2");
post.getCommentList().add(comment1);
post.getCommentList().add(comment2);
// 영속화 작업 수행
entityManager.persist(post);
entityManager.flush();
}
PERSIST 옵션으로 인하여, post 엔티티 영속화 시, [comment1, comment2] 또한 영속화 됩니다.
위 코드를 실행하였을 때, 실행되는 SQL 은 아래와 같습니다.
INSERT INTO POST (POST_ID, TITLE) VALUES (0, '게시글 제목');
INSERT INTO COMMENT (COMMENT_ID, CONTENT, POST_ID) VALUES (0, '댓글 1', 0);
INSERT INTO COMMENT (COMMENT_ID, CONTENT, POST_ID) VALUES (1, '댓글 2', 0);
하위 엔티티까지 병합 작업을 지속합니다.
조회한 Post Entity와 Comment Entity를 수정할때,
Post Entity를 Merge 하면 하위 엔티티인 Comment Entity도 Merge 됩니다.
@Test
public void 부모엔티티_merge시_자식_엔티티도_함께_merge() {
Post post = new Post();
post.setTitle("게시글 제목");
Comment comment1 = new Comment();
comment1.setContent("댓글 1");
Comment comment2 = new Comment();
comment2.setContent("댓글 2");
post.getCommentList().add(comment1);
post.getCommentList().add(comment2);
// 영속화 작업 수행 및 영속성 컨텍스트 초기화
entityManager.persist(post);
entityManager.flush();
entityManager.clear();
Post savedPost = entityManager.find(0L, Post.class);
Comment savedComment = entityManager.find(0L, Comment.class);
// 엔티티 수정
savedPost.setTitle("게시글 수정 제목");
savedComment.setContent("댓글 수정 1);
// merge 작업 수행
entityManager.merge(savedPost);
entityManager.flush();
}
MERGE 옵션으로 인하여, post 엔티티 merge 시, comment1 또한 merge 됩니다.
위 코드를 실행하였을 때, 실행되는 SQL 은 아래와 같습니다.
...
SELECT * FROM POST WHERE POST_ID = 0;
SELECT * FROM COMMENT WHERE COMMENT_ID = 0;
UPDATE POST SET TITLE = '게시글 수정 제목' WHERE POST_ID = 0;
UPDATE COMMENT SET CONTENT = '댓글 수정 1' WHERE COMMENT_ID = 0;
하위 엔티티까지 삭제 작업을 지속합니다.
Post Entity를 삭제하면 연관된 하위 엔티티인 Comment Entity도 삭제됩니다.
@Test
public void 부모엔티티_삭제시_자식_엔티티도_함께_삭제() {
Post post = new Post();
post.setTitle("게시글 제목");
Comment comment1 = new Comment();
comment1.setContent("댓글 1");
Comment comment2 = new Comment();
comment2.setContent("댓글 2");
post.getCommentList().add(comment1);
post.getCommentList().add(comment2);
// 영속화 작업 수행 및 영속성 컨텍스트 초기화
entityManager.persist(post);
entityManager.flush();
entityManager.clear();
Post savedPost = entityManager.find(0L, Post.class);
// remove 작업 수행
entityManager.remove(savedPost);
entityManager.flush();
}
REMOVE 옵션으로 인하여, post 엔티티 remove 시, [comment1,comment2] 또한 remove 됩니다.
위 코드를 실행하였을 때, 실행되는 SQL 은 아래와 같습니다.
...
SELECT * FROM POST WHERE POST_ID = 0;
DELETE FROM POST WHERE POST_ID = 0;
DELETE FROM COMMENT WHERE COMMENT_ID = 0;
DELETE FROM COMMENT WHERE COMMENT_ID = 1;
데이터베이스로부터 엔티티 값을 다시 읽어옵니다.
즉, 영속성 컨텍스트에 저장되어 있는 값을 새로고침 합니다.
Post Entity를 Refresh하면 연관된 하위 엔티티인 Comment Entity도 Refresh됩니다.
영속성 컨텍스트에 더이상 해당 엔티티를 관리하지 않습니다.
Post Entity를 Detach하면 연관된 하위 엔티티인 Comment Entity도 Detach됩니다.