고아 객체

Mina Park·2022년 9월 11일
0

1. 기본개념

  • 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제
  • orphanRemoval = true
  • 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제되는 기능
  • @OneToOne, @OneToMany에서만 가능
@Entity
public class Parent {
    @Id
    @GeneratedValue
    private Long id;

    private String name;

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

    //연관관계 편의 메소드
    public void addChild(Child child) {
        childList.add(child);
        child.setParent(this);
    }
}
 			Child child1 = new Child();
            Child child2 = new Child();
            Parent parent = new Parent();
            parent.addChild(child1);
            parent.addChild(child2);

            em.persist(parent);

            em.flush();
            em.clear();

            Parent findParent = em.find(Parent.class, parent.getId());
            findParent.getChildList().remove(0); //첫번째 자식 삭제

            tx.commit();
  • 컬렉션에서 빠진 첫번째 자식은 DB에서 자동 삭제


[참고] 개념적으로 부모를 제거하면 자식은 고아가 됨 => CascadeType.REMOVE처럼 동작

@Entity
public class Parent {
    @Id
    @GeneratedValue
    private Long id;

    private String name;

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

    //연관관계 편의 메소드
    public void addChild(Child child) {
        childList.add(child);
        child.setParent(this);
    }
}
 			Child child1 = new Child();
            Child child2 = new Child();
            Parent parent = new Parent();
            parent.addChild(child1);
            parent.addChild(child2);

            em.persist(parent);

            em.flush();
            em.clear();

            Parent findParent = em.find(Parent.class, parent.getId());
            em.remove(findParent); 
            //부모를 삭제 => 모든 자식도 삭제
            //cascade.ALL 옵션이 없더라도 컬렉션 자체가 없어지는 것이므로

            tx.commit();

📌 참조하는 곳이 하나일 때만(특정 엔티티가 단독 소유) 사용!!!


3. 영속성 전이 + 고아 객체, 생명주기

  • CascadeType.ALL + orphanRemoval = true
  • 스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove()로 제거
  • 두 옵션을 다 활성화할 경우, 부모 엔티티를 통해서 자식의 생명주기 관리 가능
    • 도메인 주도 설계(DDD)의 Aggregate Root 개념을 구현할 때 유용함

0개의 댓글