특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속화하고 싶을 때 사용하는 옵션
ex) 부모 엔티티를 저장할 때, 자식 엔티티도 함께 저장
부모 엔티티)
@Entity
public class Parent {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent")
private List<Child> childList = new ArrayList<>();
// 연관관계 메소드
public void addChild(Child child) {
childList.add(child);
child.setParent(this);
}
}
자식 엔티티)
@Entity
public class Child {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
CASCADE 옵션을 키지 않고, 엔티티를 저장할 때)
Parent parent = new Parent();
Child child1 = new Child();
Child child2 = new Child();
// 양방향 값 세팅
parent.addChild(child1);
parent.addChild(child2);
// 저장!
em.persist(parent);
em.persist(child1);
em.persist(child2);
CASCADE 옵션
으로 부모 엔티티를 저장할 때, 연관된 자식 엔티티도 함께 저장되도록 할 수 있다부모 엔티티에서 cascade 옵션을 켜준다.
// CASCADE 옵션 설정
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> childList = new ArrayList<>();
부모 엔티티만 저장할 때, 연관된 자식 엔티티도 함께 저장된다.
Parent parent = new Parent();
Child child1 = new Child();
Child child2 = new Child();
// 양방향 값 세팅
parent.addChild(child1);
parent.addChild(child2);
// 저장!
// parent 중심 개발 시, parent를 persist하면 관련된 child들이 함께 persist 되도록 하고 싶다. -> CASCADE 옵션을 사용한다.
em.persist(parent);
// CASCADE 속성을 설정하면 하나씩 persist안해도 됨
//em.persist(child1);
//em.persist(child2);
ALL: 모두 적용
PERSIST: 영속
REMOVE: 삭제
MERGE: 병합
REFRESH: REFRESH
DETACH: DETACH
아무 곳에나 남발하면 큰일난다.
운영과 관리가 안되기 때문에, 단일 엔티티에 종속적일 때만 사용한다.
ex) Child는 Parent에만 종속되어 있기 때문에, CASCADE 옵션 사용에 문제가 없다
BUT, Parent뿐만 아니라 Member에도 종속되어 있다면?
-> CASCADE 옵션 사용 X, 따로따로 관리
단일 엔티티에 종속적일 때만 사용하며, 양방향 매핑 시, @OneToMany, @OneToOne이 걸린 컬럼에 사용한다.
예를 들어, Post, Image 엔티티가 있고, 1:N의 관계, 양방향이며, Image가 Post에만 종속적일 때 사용할 수 있는 것이다.
Image에 Post의 외래키가 있을 것이고, 양방향이기 때문에 Post에는 List<Image> images
가 있을 것이다.
@OneToMany(mappedBy = "post")
List<Image> images = new ArrayList<>();
이 때, images에 cascade옵션을 사용하면 된다.
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
List<Image> images = new ArrayList<>();
Post가 삭제될 때, images도 함께 삭제된다.
고아는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 의미한다.
orphanRemoval = true
옵션을 통해 고아가 된 객체를 자동으로 삭제할 수 있다.
부모 엔티티에서 CASCADE 옵션과 고아 객체를 자동 삭제하는 옵션을 켜준다.
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
고아 객체를 의도적으로 만들어본다.
// findParent의 childList에는 2개의 child객체가 있다. (위 참조)
Parent findParent = em.find(Parent.class, parent.getId());
findParent.getChildList().remove(0);
CASCADE 옵션없이 'orphanRemoval = true' 옵션만 켜두면, CascadeType.REMOVE처럼 동작한다
@OneToMany(mappedBy = "parent", orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
Parent findParent = em.find(Parent.class, parent.getId());
em.remove(findParent);
CASCADE와 마찬가지로, 단일 엔티티에 종속적일 때만 사용해야 한다.
@OneToOne, @OneToMany만 가능
CascadeType.ALL
+ orphanRemoval = ture
두 옵션을 모두 활성화하면 부모 엔티티를 통해서 자식의 생명주기를 관리할 수 있다.