cascade 옵션이란 @OneToMany 나 @ManyToOne에 옵션으로 줄 수 있는 값이다.
Entity의 상태 변화를 전파시키는 옵션이다.
만약 Entity의 상태 변화가 있으면 연관되어 있는(ex. @OneToMany, @ManyToOne) Entity에도 상태 변화를 전이시키는 옵션이다.
기본적으로는 아무 것도 전이시키지 않는다.
Entity의 상태는 크게 4가지 종류가 있다.
1. Transient
: 객체를 생성하고, 값을 주어도 JPA나 hibernate가 그 객체에 관해 아무것도 모르는 상태. 즉, 데이터베이스와 매핑된 것이 아무것도 없다.
2. Persistent
: 저장을 하고나서, JPA가 아는 상태(관리하는 상태)가 된다. 그러나 .save()를 했다고 해서, 이 순간 바로 DB에 이 객체에 대한 데이터가 들어가는 것은 아니다. JPA가 persistent 상태로 관리하고 있다가, 후에 데이터를 저장한다.(1차 캐시, Dirty Checking(변경사항 감지), Write Behind(최대한 늦게, 필요한 시점에 DB에 적용) 등의 기능을 제공한다)
3. Detached
: JPA가 더이상 관리하지 않는 상태. JPA가 제공해주는 기능들을 사용하고 싶다면, 다시 persistent 상태로 돌아가야한다.
4. Removed
: JPA가 관리하는 상태이긴 하지만, 실제 commit이 일어날 때, 삭제가 일어난다.
cascade는 이러한 상태변화를 전이시키는 것이다.
Parent - child 관계에 있는 도메인에 적용할 수 있다.
Post 도메인과 Comment 도메인을 만들어 적용해보겠다.
Post 도메인에는 id, title, comments(comment 엔티티와 OneToMany 관계)가 존재하고, convenient method로 addComment 메서드를 만들어준다.
Comment 도메인에는 id, comment, post(Post 엔티티와 ManyToOne 관계) 가 존재한다.
게시글이 존재하고, 해당 게시물에 달린 댓글들은 만약 이 게시글이 저장되거나 삭제되면 같이 저장되거나, 삭제되어야한다고 가정한다.
Runner에서 post를 하나 생성하고, 해당 post에 두 개의 댓글을 넣어보겠다.
이 상태로 실행하면, post만 저장해주었기 때문에 post 테이블에만 데이터가 저장될 것이다.
여기서 cascade옵션을 주면 comment도 같이 저장이된다.
Post라는 인스턴스가 Transient에서 Persistent 상태로 넘어갈 때, child 객체(Comment)도 같이 Persistent 상태가 되면서 같이 저장이 되는 것이다.
cascade remove옵션도 주고나서 삭제하면 게시글을 지우면 댓글들도 같이 삭제된다.
일반적으로는 CascadeType.ALL 옵션을 줘서 사용한다.
이해가 잘 되네요. 고맙습니다.