JPA 연관 관계 - 고아 객체

목차

고아 객체란?

부모 엔티티와 연관관계가 끊어진 자식 엔티티

고아 객체 제거

  • 부모 엔티티와 연관관계 가 끊어진 자식 엔티티를 자동으로 제거
  • @OneToOne, @OneToMany 만 가능하다.
    • orphanRemoval = true
@Entity
@Getter
@Setter
public class Parent {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
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);
}
}
public class JpaMain {
public static void main(String[] ars) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello");
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction transaction = em.getTransaction();

transaction.begin();
try {
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 savedParent = em.find(Parent.class, parent.getId());
savedParent.getChildList().remove(0);

transaction.commit();
} catch (Exception e) {
transaction.rollback();
} finally {
em.close();
}
entityManagerFactory.close();
}
}
  • Parent 에서 Child를 삭제할 때 delete 쿼리가 발생하게 된다.
Hibernate: /* insert hellojpa.Parent */ insert into Parent (id, name) values (null, ?)
Hibernate: /* insert hellojpa.Child */ insert into Child (id, name, parent_id) values (null, ?, ?)
Hibernate: /* insert hellojpa.Child */ insert into Child (id, name, parent_id) values (null, ?, ?)
Hibernate: select parent0_.id as id1_6_0_, parent0_.name as name2_6_0_ from Parent parent0_ where parent0_.id=?
Hibernate: select childlist0_.parent_id as parent_i3_2_0_, childlist0_.id as id1_2_0_, childlist0_.id as id1_2_1_, childlist0_.name as name2_2_1_, childlist0_.parent_id as parent_i3_2_1_ from Child childlist0_ where childlist0_.parent_id=?
Hibernate: /* delete hellojpa.Child */ delete from Child where id=?

고아 객체 - 주의

  • 참조하는 곳이 하나 일 때 사용해야 한다.
  • 특정 엔티티가 개인 소유할 때 사용한다.
  • 부모를 제거하면 자식은 고아가 된다. 따라서 고아 객체 제거 기능을 활성화 하면, 부모를 제거할 때 자식도 함께 제거된다.(CascadeType.REMOVE 처럼 동작)

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

  • 스스로 생명 주기를 관리하는 엔티티는 em.persist() 로 영속화, em.remove() 로 제거
  • 두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식 엔티티 생명 주기를 관리할 수 있다.
  • 도메인 주도 설계(DDD) 의 Aggregate Root 개면을 구현할 때 유용하다.
Share