[Spring] 영속성 전이

이연우·2025년 8월 19일

TIL

목록 보기
89/100

🌱 영속성 전이(Cascade)

  • 부모 엔티티에 저장/삭제 같은 작업을 하면,
    연관된 자식 엔티티에도 자동으로 같은 작업이 전파되는 기능
  • 💡 중요: 지연 로딩(Lazy) / 즉시 로딩(Eager) 과는 전혀 관련 ❌

📝 예시 (기본 동작)

  • CategoryProduct (1:N 관계)
  • 기본적으로는 CategoryProduct를 각각 em.persist() 해야 함
em.persist(category);
em.persist(product1);
em.persist(product2);

👉 결과: INSERT SQL 3번 실행

⚡ Cascade 적용 (cascade = CascadeType.ALL)

@OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
private List<Product> productList = new ArrayList<>();
  • 이제 em.persist(category) 한 번만 호출해도
    • category
    • product1, product2
      모두 INSERT

👉 부모만 저장해도 자식까지 같이 저장됨 🎉


📚 사용 방법과 주의점

  • 영속성 전이는 연관관계 매핑과는 아무 관련이 없음

🛠️ Cascade 종류

속성의미
ALL모든 작업 전이 (저장, 삭제 등)
PERSIST저장 전이
REMOVE삭제 전이
MERGE병합 전이 (거의 사용 ❌)
REFRESH새로고침 전이 (거의 사용 ❌)
DETACH준영속 전이 (거의 사용 ❌)

📌 Cascade 사용 시점

✅ 쓰는 경우 (생명 주기가 완전히 종속일 때)

  • 블로그 글 ↔ 댓글 📝
  • 상품 ↔ 상품 이미지 🖼️

❌ 안 쓰는 경우 (자식이 독립적으로 존재 가능할 때)

  • 작가 ↔ 책 📚 (작가가 없어도 책은 남을 수 있음)

🧩 고아 객체 (Orphan Removal)

  • 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Product> productList = new ArrayList<>();
  • 부모 컬렉션에서 product를 제거하면 → 자동으로 DELETE 실행
  • 즉, 부모가 버린 자식은 DB에서도 삭제됨 🗑️

⚠️ 주의 사항

  1. 참조하는 곳이 하나일 때만 사용 (완전 종속 관계일 때만)

  2. @OneToOne, @OneToMany에서만 사용 가능

  3. 부모 엔티티 삭제 시 → 자식 엔티티는 고아 객체가 되어 자동 삭제

  4. CascadeType.REMOVE와 비슷하게 동작

💡 Cascade vs Orphan Removal

기능CascadeOrphan Removal
역할부모 작업(저장/삭제 등)을 자식에게 전이부모와 관계 끊어진 자식 자동 삭제
중점부모 → 자식 작업 전파관계 없는 자식 정리
적합 상황부모와 자식이 함께 생성/삭제되는 경우부모가 자식을 완전히 관리하는 경우
예시em.persist(parent)
→ 자식도 함께 저장
parent.getChildList().remove(child)
→ DB에서 자식 삭제

🧠 요약 정리

구분정의설정 방법장점주의점
Cascade
(영속성 전이)
부모 엔티티 작업(저장·삭제 등)을 자식 엔티티에도 자동 전파cascade = CascadeType.ALL- 부모만 저장/삭제해도 자식 처리
- 코드 단순화
- 독립적 엔티티에는 부적절
- 원치 않는 전이 위험 ⚠️
Orphan Removal
(고아 객체 삭제)
부모와 관계 끊어진 자식을
자동 삭제
orphanRemoval = true- 부모가 자식 생명주기 완전 관리
- 컬렉션 제거 시 DB 자동 삭제
- 참조 하나일 때만 안전
- 부모 삭제 시
자식 전부 삭제 ⚠️
Cascade + Orphan Removal부모가 자식 생명주기를
100% 관리
cascade = ALL, orphanRemoval = true- 도메인 주도 설계(DDD) 활용
- 자식 Repo 불필요
- 부모 삭제 시
자식도 모두 삭제됨 ⚠️

0개의 댓글