🌿SPRING/🍀공부 [SPRING]

[SPRING] [JPA] cascade Type 영속성 전이

디카페인라떼 2022. 9. 1. 13:52
  • 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을때 사용
  • 양방향 매핑시에만 가능
  • @OneToOne@OneToMany@ManyToOne 연관 관계가 있는 어노테이션에 cascade() 지원

eg. 부모 엔티티 저장시 자식 엔티티도 저장하도록 하는 경우

더보기

❗ 쓰면 안되는 경우 

=> 자식의 연관 관계가 2개 이상일때

ex) C라는 엔티티가 A와 B에 의해서 관리된다


Cascade 종류
  • ALL: 모든 Cascade를 적용
  • PERSIST: 엔티티를 영속화할 때, 연관된 엔티티도 함께 유지
  • MERGE: 엔티티 상태를 병합(Merge)할 때, 연관된 엔티티도 모두 병합
  • REMOVE: 엔티티를 제거할 때, 연관된 엔티티도 모두 제거
  • DETACH: 부모 엔티티를 detach() 수행하면, 연관 엔티티도 detach()상태가 되어 변경 사항 반영 X
  • REFRESH: 상위 엔티티를 새로고침(Refresh)할 때, 연관된 엔티티도 모두 새로고침
더보기

CASCADE 의 옵션은 ALL, PERSIST, REMOVE, MERGE, REFRESH, DETACH 가 있지만

주로 사용되는건 ALL, PERSIST, REMOVE 정도이고 실무에서 사용되는 건 ALL, PERSIST

ALL
  • 상위 엔티티에서 하위 엔티티로 모든 작업을 전파

 

PERSIST
  • 하위 엔티티까지 영속성 전달
  • 부모 엔티티를 저장할 때 연관된 자식 엔티티도 같이 저장
  • 그러나 부모 엔티티 삭제시에는 자식엔티티 삭제안됨 (에러발생!)

 

REMOVE
  • 부모 엔티티를 삭제할 때 연관되어 있는 자식엔티티도 같이 삭제하는 옵션
  • Parent 클래스의 @OneToMany 의 cascade 값을 REMOVE 로 변경하고 실행하면 delete query 가 세 개가 나가 자식들도 삭제
  • 이 뿐만 아니라 이 상태의 전이가 하위로 계속해서 발생.

orphanRemoval  고아 객체
orphanRemoval = true
  • 부모 엔티티와 연관 관계가 끊어진 자식 엔티티
  • 옵션으로 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제 가능

 


❓❗ REMOVE vs orphanRemoval  차이점

비교 결과

  • 부모 엔티티 삭제
    • CascadeType.REMOVE와 orphanRemoval = true는 부모 엔티티를 삭제하면 자식 엔티티도 삭제한다.
  • 부모 엔티티에서 자식 엔티티 제거
    • CascadeType.REMOVE는 자식 엔티티가 그대로 남아있는 반면, orphanRemoval = true는 자식 엔티티를 제거한다.

주의점

두 케이스 모두 자식 엔티티에 딱 하나의 부모 엔티티가 연관되어 있는 경우에만 사용해야 한다.

 

예를 들어 Member(자식)을 Team(부모)도 알고 Parent(부모)도 알고 있다면, CascadeType.REMOVE 또는 orphanRemoval = true를 조심할 필요가 있다. 자식 엔티티를 삭제할 상황이 아닌데도 어느 한쪽의 부모 엔티티를 삭제했거나 부모 엔티티로부터 제거됐다고 자식이 삭제되는 불상사가 일어날 수 있기 때문이다.

 

그러므로 @OneToMany에서 활용할 때 주의를 기울이고, @ManyToMany에서는 활용을 지양하자.

 


참고 ) 엔티티의 상태

  • Transient : JPA가 엔티티를 모르는 상태, 즉 최초의 객체들이 생성된 단계
  • Persistent : JPA가 관리중인 상태, DB에 들어간 것을 의미하지는 않는다. 즉 save() 메소드를 사용했다고 해서 바로 DB에 insert 되는 것은 아니며 이 상태를 Persistent라고 부른다.( 1차 캐시, Dirty Checking, Write Behind 등)
  • Detached : JPA가 더이상 관리하지 않는 상태.
  • Removed : JPA가 관리하긴 하지만 삭제하기로 한 상태.