[JPA] 영속성 전이 CASCADE :: 잡다한 프로그래밍
반응형

JPA에서 연관된 객체들을 저장하거나 삭제할 때, 매번 em.persist() 또는 em.remove()를 수동으로 호출하는 건 매우 번거롭다.

이때 등장하는 개념이 영속성 전이(Cascade)고아 객체 제거(orphanRemoval) 이다.

영속성 전이(Cascade)란?

연관된 엔티티도 자동으로 함께 영속성 상태로 관리하고 싶을 때 사용하는 기능입니다.

예를 들어, 게시글(Parent)과 댓글(Child)의 관계가 있다고 할 때, 게시글을 저장할 때 댓글도 자동으로 저장되길 원한다면 cascade가 필요합니다.

@Entity
public class Parent {
    @Id @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)  // 또는 ALL
    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;
}

 

Child child1 = new Child();
Child child2 = new Child();

Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);

em.persist(parent);  // ✅ child1, child2도 함께 persist됨
// cascade옵션을 쓰지 않았다면 child1, child2를 두번 persist해줘야함

언제 사용하는가?

  • 연관된 엔티티의 생명주기를 부모가 전적으로 관리할 때
  • 대표적인 예: 게시글 - 댓글, 주문 - 주문상품, 설문 - 질문 등 "소유 관계"

여러 주인이 존재하는 연관관계에서는 절대 사용하면 안 됨
→ ex. 여러 게시글이 하나의 댓글을 공유하는 경우 (잘못된 모델링이지만)

🎯 Cascade 옵션 종류

옵션 설명
ALL 모든 Cascade 기능을 포함
PERSIST 연관 객체도 persist() 자동 호출
MERGE 병합 시 함께 병합
REMOVE 삭제 시 함께 삭제
REFRESH DB로부터 갱신할 때 함께 갱신
DETACH 영속성 컨텍스트에서 분리할 때 함께 분리

🧹 고아 객체 제거 (orphanRemoval)

부모 객체에서 연관관계를 끊어버리면, JPA가 해당 자식 엔티티를 자동으로 DELETE 하는 기능

@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
Parent parent = em.find(Parent.class, 1L);
parent.getChildList().remove(0); // 해당 child 엔티티 DELETE 쿼리 발생

 

  • JPA가 자동으로 DELETE FROM child WHERE id = ? 실행
  • 연관관계가 끊어진 자식 엔티티를 고아(Orphan) 라고 판단하고 제거

언제 사용하는가?

  • Cascade와 마찬가지로 참조하는곳이 하나일 때 사용
  • @One ToOne, @OneToMany만 사용가능

 

Cascade vs OrphanRemoval 차이점

구분 Cascade OrphanRemoval
역할 부모 저장/삭제 시 자식도 함께 처리 연관관계 끊긴 자식을 자동 삭제
대상 persist, remove 등 엔티티 상태 변화 컬렉션에서 제거된 객체
필요 조건 연관관계 유지 참조가 제거됨 (null 또는 List.remove())
주의사항 생명주기 공유일 때만 사용 참조하는 곳이 하나일 때만 사용

 

CascadeType.ALL + orphanRemoval = true

이 둘을 함께 사용하면 아래와 같은 설계가 가능해집니다:

  • parent.addChild(child) → 자동으로 저장
  • parent.getChildList().remove(child) → 자동 삭제
  • em.remove(parent) → 연관된 child도 자동 삭제

이 조합은 부모 엔티티를 통해 자식의 생명주기를 완벽하게 제어하는 것을 의미합니다.

반응형

'프로그래밍 > JPA' 카테고리의 다른 글

[JPA] 값 타입과 불변 객체  (2) 2025.07.23
[JPA] 값 타입  (1) 2025.07.22
[JPA] 즉시 로딩과 지연 로딩  (2) 2025.07.16
[JPA] 프록시와 연관관계 관리  (0) 2025.07.15
[JPA] Mapped Superclass - 매핑 정보 상속  (0) 2025.07.03

+ Recent posts