JPA에서 연관된 엔티티들도 함께 영속성 작업을 적용할 수 있게 해주는 기능
부모 엔티티에서 어떤 작업(저장, 삭제 등)을 하면, 연관된 자식 엔티티에도 동일한 작업이 자동으로 전이(cascade)된다.
연관된 엔티티의 생명주기가 하나로 묶여 있을 때, 반복적인 persist(), remove() 등을 줄일 수 있다. 주로 부모-자식 관계에서 자식이 독립적으로 관리되지 않을 때 사용한다.
부모는 One에 해당하고 자식은 Many에 해당된다.
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
private List<Child> children = new ArrayList<>();
}
@Entity
public class Child {
@Id @GeneratedValue
private Long id;
@ManyToOne
private Parent parent;
}
Parent parent = new Parent();
Child child1 = new Child();
Child child2 = new Child();
child1.setParent(parent);
child2.setParent(parent);
parent.getChildren().add(child1);
parent.getChildren().add(child2);
em.persist(parent); // parent만 저장해도 child1, child2도 함께 저장
| 종류 | 설명 |
|---|---|
PERSIST | 부모 엔티티 저장 시 자식도 저장 |
MERGE | 부모 엔티티 병합(업데이트) 시 자식도 병합 |
REMOVE | 부모 엔티티 삭제 시 자식도 삭제 |
REFRESH | 부모 엔티티 새로고침 시 자식도 새로고침 |
DETACH | 부모 엔티티 영속성 분리 시 자식도 분리 |
ALL | 위 모든 옵션을 포함 |
부모 엔티티와 연관 관계가 끊어져서, 더 이상 참조되지 않는 고립된 자식 엔티티를 자동으로 삭제해주는 기능
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> children = new ArrayList<>();
}
@Entity
public class Child {
@Id @GeneratedValue
private Long id;
@ManyToOne
private Parent parent;
}
// orphanRemoval = true 작동 방식
// 부모와 자식 관계 설정
Parent parent = new Parent();
Child child = new Child();
child.setParent(parent);
parent.getChildren().add(child);
em.persist(parent); // 부모와 자식 저장
// 이후 자식 제거
parent.getChildren().remove(child); // 리스트에서 제거하면
child.setParent(null); // 연관 관계도 끊기고
// 트랜잭션 커밋 시 child는 DB에서 자동 삭제됨!
orphanRemoval = true는 자식 엔티티가 부모와의 관계에 종속적일 때, 부모가 자식을 관리하고 자식이 독립적으로 존재하지 않아야 할 때 사용한다.
-> @OneToOne, @OneToMany 관계에서만 사용 가능하며 @ManyToOne, @ManyToMany에서는 사용할 수 없음
예) 게시글의 댓글, 주문의 주문 상품 등
| 기능 | 설명 |
|---|---|
CascadeType.REMOVE | 부모가 삭제될 때 자식도 삭제됨 |
orphanRemoval = true | 부모와의 관계가 끊어질 때 자식 삭제됨 (부모는 남아있음) |
→ 둘을 같이 사용하면 부모 삭제 시, 관계 끊김 시 모두 자식이 삭제
단순히 컬렉션에서 remove()만 해도 실제 DB에서 DELETE가 실행되므로 신중하게 사용해야한다.
오늘은 JPA의 연관 관계 매핑 중 영속성 전이(Cascade)와 고아 객체 제거(Orphan Removal)에 대해 공부했다.
둘 다 연관된 엔티티 간의 생명주기를 함께 관리할 수 있도록 도와주는 기능이다.
Cascade와 orphanRemoval은 유사해 보이지만 트리거되는 시점과 상황이 다르며, 함께 사용할 수도 있다.