JPA에서 @OneToMany
같은 연관관계 매핑에 사용하는 애너테이션을 사용할 때 cacade 옵션과 orphanRemoval 옵션을 볼 수 있다.
이 옵션에 대해서는 간단하게 요약하면 아래와 같다.
CascadeType 그리고 orphanRemoval
cascade = CascadeType.REMOVE
- 이 옵션은 부모 엔티티의 라이프 사이클 변경이 자식 엔티티로 전파되도록 지정하는 옵션이다.
- 부모 엔티티가 삭제될 때 자식 엔티티들도 같이 삭제된다.
orphanRemove = true
- 이 옵션은 부모 엔티티의 컬렉션에서 제거된 자식 엔티티들을 자동으로 삭제하도록 지정하는 옵션이다.
- 만약 부모 엔티티의 컬렉션에서 자식 엔티티가 제거되면, 영속성 컨텍스트에서도 해당 자식 엔티티에 대해 삭제 작업이 즉시 수행된다.
두 옵션에 대해 차이점을 서술하는 글들은 많이 있다.
이 글은 두 옵션의 차이점이 아닌 두 옵션을 명시적으로 모두 사용하는 의미에 대해서 정리하고자 한다.
둘이 비슷한거 아니야? 왜 같이 사용해?
1. 명시적인 의도 표현
먼저, cascade = CascadeType.REMOVE
옵션은 부모 엔티티가 삭제될 때 자식 엔티티도 함께 삭제한다고 명시적으로 선언하는 것이다.
다시 말해, 라이프 사이클의 전이에 대한 것이다.
orphanRemoval = true
옵션은 컬렉션에서의 삭제에 대한 것이다.
부모 엔티티의 컬렉션에 속한 자식 엔티티가 제거됐을 때(=자식 엔티티가 고아가 됐을 때) 자식 엔티티의 처우에 대한 옵션이다.
이 옵션이 true
면 고아 객체가 된 자식 엔티티가 즉각적으로 영속성 컨텍스트에서 제거됨을 선언한 것으로 볼 수 있다.
2. 삭제 시점의 차이cascade = CascadeType.REMOVE
옵션만 사용할 경우, 부모 엔티티의 라이프 사이클 변경에 따라 자식 엔티티가 삭제되지만, orphanRemoval = true
옵션을 사용하면 부모 엔티티의 컬렉션에서 자식 엔티티를 제거할 때 영속성 엔티티에서 즉시 삭제된다.orphanRemoval
옵션은 특정 컬렉션에서 자식 엔티티를 제거하면서 영속성 엔티티에서 바로 삭제되기를 원할 때 더 민감하게 동작할 수 있다.
결론
정리하면, CascadeType.ALL
만 사용해도 기본적으로 관련 자식 엔티티를 삭제할 수 있지만, orphanRemove = true
를 사용하면 삭제 동작에 대한 명시적인 제어와 특정 시점에서의 자식 엔티티 삭제를 더 강화할 수 있다.