Cascade (영속성 전이, transitive persistence) : 특정 엔티티 영속 상태 만들 때 연관된 엔티티도 함께 영속 상태 만드는 경우
1. 영속성 전이 : 저장
부모 엔티티 저장 시 자식 엔티티 함께 저장.
jpa에서 엔티티 저장 시 연관된 모든 엔티티는 영속 상태여야 하기 때문에 부모 엔티티 저장하려면 그와 연관된 자식 엔티티 각각 영속 상태로 만들어야 함.
Parent 엔티티에 @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST) 옵션 적용 시 자식 엔티티까지 한번에 영속화하여 저장한다.
2. 영속성 전이 : 삭제
CascadeType.REMOVE
부모 엔티티 삭제 시 연관된 자식 엔티티도 함께 삭제됨.
cancade = {CascadeType.PERSIST, Cascade.REMOVE}로 한 번에 여러 속성 지정 가능.
CascadeType.PERSIST, REMOVE는 em.persist(), em.remove() 실행 시 바로 전이되는 것 아니라, 플러시 호출 시 전이 발생.
고아 객체 (orphan)
부모 엔티티와 연관관계 끊어진 자식 엔티티.
JPA는 고아 객체를 자동으로 삭제하는 기능을 제공한다.
이 기능을 활용하면 부모 엔티티의 컬렉션에서 자식 엔티티의 참조만 제거하면 자식 엔티티가 자동으로 삭제되도록 할 수 있다.
참조하는 곳이 '하나일 때'만 사용해야 함.
@OneToMany(mappedBy = "parent", orphanRemoval = true)
cascade REMOVE와 orphanRemoval의 차이점?
둘 다 부모 엔티티 삭제 시 자식 엔티티도 삭제한다.
다른점은 관계 끊는 것에 대한 응답이다.
자식 값에 null 주었을 때 orphanRemoval=true는 관계가 끊어진 child를 자동으로 제거한다.
CascadeType.REMOVE는 관계가 끊어진 child를 자동 제거하지 않는다. (관계가 끊어졌다는 것을 제거로 보지 않기 때문)
orphanRemoval은 관계 여부에 따라 달라지기 때문에 자식 엔티티가 삭제된 게 아니더라도 부모와 관계 끊어지면 지워진다. 따라서 관계 끊어져도 자식 엔티티 존재해야 하는 상황에서 사용하면 안됨.
두 케이스 모두 자식 엔티티에 딱 하나의 부모 엔티티가 연관되어 있는 경우에만 사용해야 한다.
orphanRemoval이 cascade REMOVE 보다 큰 개념.
영속성 전이 + 고아 객체
CascadeType.ALL + orphanRemoval = true 동시에 사용하면 부모 엔티티 통해서 자식의 생명 주기 관리할 수 있음.
<참고>
https://velog.io/@sa1341/JPA-영속성-전이
cascade REMOVE와 orphanRemoval의 차이점 : https://modimodi.tistory.com/22
https://sudo-minz.tistory.com/144