[JPA] CascadeType.REMOVE 와 orphanRemoval의 차이점

`CascadeType.REMOVE` `orphanRemoval = true`  JPA에서 엔티티 간의 관계를 관리할 때 사용하는 두 가지 기능으로, 각기 다른 상황에서 엔티티를 삭제하는 데 사용된다.

CascadeType.REMOVE

  • 기능 : `CascadeType.REMOVE` 는 부모 엔티티가 삭제될 때, 관련된 엔티티도 함께 삭제하도록 설정하는 기능이다.
  • 사용 시기 : 부모 엔티티와 자식 엔티티가 강한 의존 관계를 가지고 있어서 부모 엔티티가 삭제 될 때 자식 엔티티도 함께 삭제되어야 하는 경우에 사용한다.
  • 예시
@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
    private List<Child> children;
}

위의 코드에서 Parent 엔티티가 삭제되면, 연관된 모든 Child 엔티티도 함께 삭제된다. 다만 , `orphanRemoval = true` 와는 달리 컬렉션에서 특정 자식 엔티티가 제거될때 해당 자식 엔티티를 데이터베이스에서 삭제하지는 않는다.

orphanRemoval

  • 기능 : `orphanRemoval = true` 는 부모 엔티티와의 관계가 끊어진 자식 엔티티를 고아 객체(orphan)라고 하며, 이러한 고아 객체를 자동으로 삭제하는 기능이다.
  • 사용 시기 : 부모 엔티티의 컬렉션에서 자식 엔티티가 제거될 때, 그 자식 엔티티가 데이터베이스에서도 삭제되어야 하는 경우에 사용한다.
  • 예시
@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "parent", orphanRemoval = true)
    private List<Child> children;
}

위의 코드에서 Parent 엔티티의 컬렉션에서 특정 Child 엔티티가 제거(연관 관계를 끊을때) 되면, 해당 Child  엔티티는 데이터베이스에서도 삭제된다. 그리고  `CascadeType.REMOVE` 와는 달리 부모 엔티티가 삭제 된다고 해서 자식 엔티티가 삭제되지는 않는다.

이를 정리하면 다음과 같다.

orphanRemoval = true  CascadeType.REMOVE 부모 엔티티 삭제 시 부모 컬렉션에서 자식 엔티티 제거 시
설정 설정 하지 않음 자식 엔티티 삭제 되지 않음 자식 엔티티 삭제
설정 설정 자식 엔티티 삭제 자식 엔티티 삭제
설정 하지 않음 설정 자식 엔티티 삭제 자식 엔티티 삭제 되지 않음
설정 하지 않음 설정 하지 않음 자식 엔티티 삭제 되지 않음 자식 엔티티 삭제 되지 않음

개발을 하다 보면 부모 엔티티를 삭제하더라도 자식 엔티티는 삭제하고 싶지 않은 경우가 있고, 연관 관계를 끊더라도 자식 엔티티를 삭제하고 싶지 않은 경우가 있다. `CascadeType.ALL`을 무작성 설정해놓고 시작하는 경우가 많았는데 주의 상황에 맞추어 적절한 설정을 사용하도록 하여야 겠다.