JPA에서의 고아 객체 처리하기

KangWook·2024년 8월 26일
0

orphanRemoval란?

orphanRemoval은 JPA에서 부모 엔티티가 자식 엔티티와의 관계를 제거할 때, 해당 자식 엔티티를 자동으로 삭제해주는 옵션이다. 이때 “고아 객체(orphan)“는 부모 엔티티와의 연관 관계가 끊어진 자식 엔티티를 의미한다. 즉, 부모 엔티티가 자식 엔티티를 더 이상 참조하지 않으면, JPA는 이 자식 엔티티를 데이터베이스에서 삭제한다.


orphanRemoval 사용 방법

orphanRemoval은 @OneToOne 또는 @OneToMany 어노테이션에 설정할 수 있고. 기본값은 false이며, 명시적으로 true로 설정해야 작동한다.

위 코드에서 orphanRemoval = true로 설정된 children 컬렉션에서 자식 엔티티를 제거하면, JPA는 해당 자식 엔티티를 자동으로 삭제된다.


orphanRemoval의 동작 원리

orphanRemoval = true를 설정한 경우, 부모 엔티티에서 자식 엔티티를 컬렉션에서 제거할 때 JPA가 데이터베이스에서 해당 자식 엔티티를 삭제하는 트리거를 발생킨다. 이것은 마치 cascade = CascadeType.REMOVE와 비슷하게 작동하지만, 중요한 차이점이 있다.

orphanRemoval과 CascadeType.REMOVE의 차이점

•	orphanRemoval은 부모가 자식을 더 이상 참조하지 않을 때 자식을 삭제하는 데 사용된다.
•	CascadeType.REMOVE는 부모 엔티티가 삭제될 때 자식 엔티티도 함께 삭제되는 방식이다.

즉, orphanRemoval은 부모-자식 간의 참조가 끊어졌을 때 동작하는 반면, CascadeType.REMOVE는 부모 엔티티가 제거될 때 동작하는 것이다.


orphanRemoval의 사용 사례

  1. 블로그 포스트와 댓글

블로그 포스트와 댓글 간의 관계를 생각해볼 수 있는데. 포스트가 삭제되지 않더라도, 특정 댓글이 포스트와의 관계에서 제거된다면 해당 댓글을 삭제하는 것이 자연스러울 수 있다. 이럴 때 orphanRemoval을 사용하면 유용하다.

  1. 쇼핑몰 주문과 주문 항목

주문 엔티티와 주문 항목 엔티티 간의 관계에서도 적용할 수 있다. 특정 주문 항목이 삭제되거나 더 이상 유효하지 않으면, 주문 엔티티에서 해당 항목을 제거하고 orphanRemoval = true 설정으로 자동으로 삭제할 수 있다.

주의할 점

orphanRemoval을 사용할 때, 자식 엔티티의 수가 많을 경우 성능에 영향을 미칠 수 있다. 자식 엔티티가 많이 포함된 컬렉션에서 자식 엔티티를 제거할 때, JPA는 일일이 삭제 작업을 수행해야 하므로 성능 저하가 발생할 수 있다.

  1. 논리적 삭제와의 충돌

일부 애플리케이션에서는 실제 삭제 대신 “논리적 삭제”를 구현할 수도 있다. 이 경우 orphanRemoval = true는 적합하지 않을 수 있습니다. 논리적 삭제는 엔티티의 상태를 변경하는 방식으로 처리하므로, 실제 데이터베이스에서 엔티티를 삭제하는 orphanRemoval과 충돌할 수 있다.

  1. 연관 관계 설정 시 주의

부모 엔티티와 자식 엔티티 간의 연관 관계 설정을 잘못하면 예상치 못한 엔티티 삭제가 발생할 수 있다. 연관 관계를 설정할 때는 항상 테스트를 통해 orphanRemoval 옵션이 의도한 대로 작동하는지 확인해야한다.


결론

JPA의 orphanRemoval 옵션은 부모-자식 엔티티 간의 연관 관계가 끊어졌을 때 자식 엔티티를 자동으로 삭제해주는 유용한 기능이다. 특히, 불필요한 데이터를 자동으로 정리할 수 있어 데이터베이스의 무결성을 유지하는 데 도움이 된다. 하지만 성능 문제나 논리적 삭제와의 충돌 가능성을 항상 염두에 두고 신중하게 사용해야 한다.

profile
꾸준히 성장하는 개발자

0개의 댓글