<추천글>[JPA] CascadeType.REMOVE vs orphanRemoval true

2022. 1. 10. 01:02[ 백엔드 개발 ]/[ Spring ]

영속성 전이와 고아 객체는 다른 개념이다. CascadeType과 orphanRemoval은 각각 영속성 전이와 고아 객체 개념에 해당한다.

 

1. CascadeType.REMOVE

- 부모 엔티티가 삭제될 때, 자식 엔티티도 함께 삭제되도록 한다.

- 부모 엔티티에 설정한다. 따라서 양방향 연관관계일 경우에만 해당한다.

- 부모를 삭제하는 것이 아닌 단순히 부모와 자식의 연관관계를 제거하는 연산에 대해서는 자식 엔티티를 삭제하지 않는다. 예를 들어 부모 엔티티에서 one-to-many로 Collection 형태의 자식 엔티티들을 가지고 있을 때, 해당 Collection에서 특정 자식 엔티티를 삭제하는 연산에 대해서는 delete 쿼리가 발생하지 않는다. 부모 엔티티가 삭제된 것이 아니기 때문이다.

 

cf. on delete cascade : 자식 엔티티에 설정하는 속성이며 부모 엔티티가 삭제될 때 자식엔티티도 함께 삭제된다. CascadeType.REMOVE은 부모 엔티티에 설정함으로써 모든 자식 엔티티가 함께 삭제되도록 하지만, on delete cascade 제약조건은 이를 추가한 자식 엔티티만이 부모 엔티티가 삭제될 때 함께 삭제된다.

 

- CascadeType.REMOVE은 RDB의 제약조건과 전혀 무관함(RDB와 객체 간 패러다임 불일치 문제중 하나)

- 반대로 on delete cascade는 RDB의 자체적인 속성으로써 참조하고 있는 테이블에 설정해주는 속성이다.

 

2. orphanRemoval = true

- 부모 엔티티가 삭제될 때 자식 인티티도 함께 삭제되는 연산이다. (CascadeType.REMOVE와 동일점)

- 부모 엔티티에 설정하는 속성이다.

- 하지만 부모 엔티티로부터 삭제된 자식 엔티티(부모를 잃어버린 자식 엔티티)도 함께 삭제하도록 한다.

- orphanRemoval 역시 RDB의 제약조건과 전혀 무관하다.

 

[정리]

- 부모 엔티티 자체를 삭제할 경우, 자식엔티티에 대해서는 CascadeType.REMOVE를 설정하던지 orphanRemoval = true 를 하던지 상관없이 삭제된다.

- 부모 엔티티는 그대로 두고, 부모 엔티티에서 자식 엔티티를 삭제할 경우, CascadeType.REMOVE의 경우에는 자식 엔티티를 삭제하지 않지만 orphanRemoval = true일 경우에는 자식 엔티티가 삭제된다.

- 두 설정 모두 부모 엔티티에서 해주는 속성이기 때문에 만약 자식 엔티티가 여러 개의 부모 엔티티를 가지고 있다면 두 설정을 주의해서 사용해야 한다.

- 즉, @OneToMany를 사용할 때 주의해야 하며 차라리 @OneToMany를 사용하지 않는 것이 낫다.

- CasecadeType.REMOVE, orphanRemoval 두 속성은 모두 RDB의 속성과 무관하며 JPA의 양방향 속성 때문에 존재하는 설정 사항이다.