Spring/JPA

[JPA] 고아 객체(ORPHAN) orphanRemoval=true

SeongHun._. 2023. 1. 14. 15:22

JPA는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제해주는 기능을 제공한다.

이러한 기능을 고아(ORPHAN) 객체 제거라고 한다.

부모 엔티티의 컬렉션에서 자식 엔티티의 참조만 제거되면 해당 자식 엔티티는 자동으로 삭제된다.

 

orphanRemoval=true

 

다음과 같이 orphanRemoval = true를 넣어주면 된다.

 

@Entity
public class Parent {

    @Id @GeneratedValue
    @Column(name = "PARENT_ID")
    private Long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST, orphanRemoval = true)
    private List<Child> childList = new ArrayList<>();
}

 

앞서 배운 CascadeType.PERSIST를 활용하여 부모 엔티티만 영속화시켜 자식 엔티티도 영속화할 수 있도록 만들자.

 

Parent parent = new Parent();
em.persist(parent);

Child child1 = new Child();
child1.setParent(parent);
parent.getChildList().add(child1);

Child child2 = new Child();
child2.setParent(parent);
parent.getChildList().add(child2);

 

이후 저장된 부모 엔티티를 불러와 childList 첫번째 인덱스에 포함된 자식 엔티티(child)와의 연결을 끊어주자.

 

Parent parent = em.find(Parent.class, 1L);
parent.getChildList().remove(0);

 

부모 엔티티(parent)에서 컬렉션에 값을 제거한 것으로 자식 엔티티가 삭제되는 것을 확인할 수 있다.

 

Hibernate: 
    delete 
    from
        child 
    where
        id=?

 

만약 orphanRemoval = true 설정을 하지 않았다면?

위와 같은 코드를 실행시켰을 때 부모 엔티티는 삭제된 자식 엔티티를 알 수 없으나, DB에 자식 엔티티는 삭제되지 않고 고아 객체로 남아있게 된다.

 

주의해야 할 점

cascade 처럼 orphanRemoval 또한 자식 엔티티가 딱 하나의 부모 엔티티와 연관되는 경우에만 사용해야 한다.

 

 

reference

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com