영속성 전이(cascade, transitive persistence)는 부모 엔티티에 한 영속성 작업(저장·병합·삭제 등)을 연관된 자식 엔티티에도 자동으로 적용하는 JPA 옵션이다. 기본값은 아무것도 전이하지 않는 것이다.
@Entity
public class Order {
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderLine> lines = new ArrayList<>();
public void addLine(OrderLine line) { lines.add(line); line.setOrder(this); }
}
orderRepository.save(order); // 주문과 함께 주문 항목들도 저장타입
PERSIST: 부모를 저장하면 자식도 저장MERGE: 부모를 병합하면 자식도 병합REMOVE: 부모를 삭제하면 자식도 삭제REFRESH: 부모를 DB에서 다시 읽으면 자식도DETACH: 부모를 영속성 컨텍스트에서 떼어 내면 자식도ALL: 위 전부
orphanRemoval = true(고아 객체 제거, orphan removal)는 부모 컬렉션에서 빠진 자식을 삭제한다. REMOVE는 부모가 삭제될 때만 동작한다는 점이 다르다.
언제 쓰나
- 자식의 생명주기가 부모에 완전히 묶여 있을 때만 쓴다. 주문과 주문 항목, 게시글과 첨부처럼 부모 없이 존재할 이유가 없는 관계
- 여러 부모가 공유하는 엔티티(회원·상품 등)에
REMOVE를 걸면, 한쪽을 지울 때 남이 쓰는 데이터까지 사라진다 - 전이는 부모 → 자식 방향으로만 의미가 있다. 자식에서 부모로 전이하는 설정은 피한다
- DB의
ON DELETE CASCADE와는 별개다. JPA cascade는 영속성 컨텍스트에 로드된 엔티티를 하나씩 처리한다(영속성 컨텍스트)
"한 덩어리로 함께 저장·삭제되는 범위"는 DDD의 애그리거트와 같은 개념이라, 애그리거트 루트에서 내부 엔티티로만 cascade를 거는 것이 자연스럽다. 관계 매핑 자체는 JPA 연관관계 매핑을 본다.
출처: Hibernate ORM User Guide: Cascading entity state transitions