1. 영속성 전이(CASCADE)란?
JPA에서 영속성 전이(Cascade)는 특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속 상태로 만드는 기능을 의미한다.
- 주로 부모-자식 관계에서 부모를 저장하면 자식도 자동으로 저장되도록 할 때 사용한다.
영속성 전이가 필요한 이유
- 부모 엔티티와 자식 엔티티를 함께 관리할 때 편리
- 연관된 엔티티의 생명주기를 일관되게 관리 가능
- 중복된 persist(), remove() 호출을 줄여 코드 간결화 가능
영속성 전이 예제
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
private List<Child> children = new ArrayList<>();
public void addChild(Child child) {
children.add(child);
child.setParent(this);
}
}
@Entity
public class Child {
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
Parent parent = new Parent();
Child child1 = new Child();
Child child2 = new Child();
parent.addChild(child1);
parent.addChild(child2);
em.persist(parent); // parent만 persist 해도 child1, child2도 함께 영속화됨
- CascadeType.PERSIST 덕분에 parent를 persist() 할 때 child1, child2도 자동으로 저장된다.
- 만약 CASCADE 설정이 없다면, em.persist(child1), em.persist(child2)를 따로 호출해야 한다.
2. CASCADE의 종류
옵션 | 설명 |
ALL | 모든 영속성 전이 적용 |
PERSIST | 부모가 persist() 될 때 자식도 함께 persist() |
REMOVE | 부모가 remove() 될 때 자식도 함께 삭제 |
MERGE | 부모가 merge() 될 때 자식도 함께 merge() |
REFRESH | 부모가 refresh() 될 때 자식도 함께 refresh() |
DETACH | 부모가 detach() 될 때 자식도 함께 detach() |
- 실무에서는 ALL, PERSIST, REMOVE가 주로 사용된다.
3. 고아 객체 제거
JPA에서는 부모-자식 관계에서 부모와의 연관 관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능을 제공하는데, 이를 고아 객체 제거(Orphan Removal)라고 한다.
* orphanRemoval = true 옵션을 사용하면 부모 객체에서 자식 객체를 remove() 하면, 자동으로 삭제된다. |
고아 객체 제거 예제
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> children = new ArrayList<>();
public void removeChild(Child child) {
children.remove(child);
child.setParent(null);
}
}
@Entity
public class Child {
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
- 부모 객체에서 children.remove(child)를 하면, 자식 객체는 자동으로 DELETE 쿼리 실행됨
고아 객체 제거 주의점
- 참조하는 곳이 하나일 때만 사용해야 한다.
- 부모 엔티티를 삭제하면, 자식도 자동으로 삭제됨 (CascadeType.REMOVE와 동일한 효과)
- @OneToOne, @OneToMany 관계에서만 사용 가능
4. 영속성 전이와 고아 객체 제거를 함께 사용할 때
CascadeType.ALL + orphanRemoval = true를 함께 사용하면, 부모 엔티티를 통해 자식 엔티티의 생명주기를 완전히 관리할 수 있다.
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> children = new ArrayList<>();
- 부모를 persist() 하면 자식도 자동 저장
- 부모를 remove() 하면 자식도 자동 삭제
- 부모에서 자식을 remove() 하면 자동으로 DELETE
언제 사용하면 좋을까?
- 부모 엔티티가 자식을 독점 관리할 때
- 도메인 주도 설계(DDD)에서 Aggregate Root 개념을 적용할 때
5. 활용 사례
회원과 주문 관계에서 활용
@Entity
public class Member {
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Order> orders = new ArrayList<>();
}
- 회원이 주문을 삭제하면, 주문도 자동으로 삭제
게시글과 댓글 관계에서 활용
@Entity
public class Post {
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
}
- 게시글이 삭제되면, 연관된 댓글도 자동 삭제
6. 정리
❗영속성 전이(CASCADE): 부모 엔티티를 persist() 할 때 자식도 함께 persist()
❗고아 객체 제거: 부모와의 연관 관계가 끊어진 자식 객체를 자동으로 삭제
❗CascadeType.ALL + orphanRemoval = true: 부모 엔티티를 통해 자식의 생명주기 완전 관리
❗실무에서는 부모가 자식을 완전히 소유할 때만 사용해야 한다.
반응형
'Backend > JPA' 카테고리의 다른 글
JPA (Spring Data JPA) - 쿼리 메소드 기능 (예제 코드) (0) | 2025.03.11 |
---|---|
JPA - 값 타입 매핑: 기본 개념부터 실무 적용까지 (0) | 2025.02.27 |
JPA - 프록시와 지연 로딩 (불필요한 데이터 조회 방지) (0) | 2025.02.24 |
JPA 고급 매핑 - 상속관계 매핑과 @MappedSuperclass (테이블 구조 상속화 및 공통 엔티티 관리) (0) | 2025.02.21 |
JPA 다양한 연관관계 매핑 개념(다중화, 일대일, 다대다, 다대일, 일대다) (0) | 2025.02.21 |