개발자꿈나무

영속성 전이, 고아 객체 본문

자바/JPA

영속성 전이, 고아 객체

망재이 2023. 8. 22. 19:26

★ 영속성 전이 : CASCADE

- 특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속상태로 만들고 싶을 때 사용하는 속성이다.

- Parent와 Child가 양방향 연관관계를 맺고 있을 때 parent 하나와 child 두 개를 영속상태로 만들려면 em.persist()를 총 3번 실행해야 한다. 만약 child가 10개라면 persist() 호출을 10번 진행해야 한다.

@OneToMany(mappedBy = "parent",cascade = CascadeType.PERSIST) //영속성 전이
private List<Child> children = new ArrayList<>();

- 그러나 위 로직처럼 영속성을 전이시킨다면 em.persist(parent)가 이루어졌을 때 자식 엔티티도 자동으로 영속상태가 된다.

Child child1 = new Child();
Child child2 = new Child();

Parent parent = new Parent();
child1.setParent(parent);
child2.setParent(parent);
parent.getChildren().add(child1);
parent.getChildren().add(child2);

em.persist(parent); // -> 부모와 연관된 자식들 저장

- 저장과 마찬가지로 삭제할 때도 parent를 삭제하면 child도 함께 삭제를 진행하고 싶으면 CascadeType.REMOVE로만 바꿔주면 된다.

@OneToMany(mappedBy = "parent",cascade = CascadeType.REMOVE) //영속성 전이
private List<Child> children = new ArrayList<>();

- 실제 실행된 쿼리를 보면 child1, child2, parent 모두를 삭제한 것을 알 수 있다.

 

⭐︎ 주의점

  • 영속성 전이는 연관관계를 매핑하는 것과 아무런 연관이 없음!!
  • 단지 엔티티를 영속화할 때 연관된 엔티티도 함께 영속할 뿐임
  • CascadeType은 ALL, PERSIST, REMOVE, MERGE, DETACH, REFRESH 등이 있다.
  • 영속성 전이를 사용할 때는 (특히 REMOVE) 연관된 엔티티가 어떤 것들이 있는지를 잘 확인해야 한다. -> 여러 개의 엔티티에 연관관계를 맺고 있을 경우 함께 삭제가 되는 경우가 발생할 수 있으니 신중하게 사용하여야 한다.

 

 

★ 고아 객체

- 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 고아 객체라고 한다.

- orphanRemoval 속성을 true로 설정하면 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제해준다.

@OneToMany(mappedBy = "parent", orphanRemoval = true) 
private List<Child> children = new ArrayList<>();
Parent findParent = em.find(Parent.class, parent.getId());
findParent.getChildren().remove(0); //child1 삭제됨

 

⭐︎ 주의

  • 영속성 전이를 사용할 때와 마찬가지로 참조하는 곳이 하나일 때 사용하여야 한다!! -> 특정 엔티티가 개인 소유할 때 사용
  • @OneToOne, @ManyToOne에서만 사용 가능

* 고아 객체 제거 기능을 활성화 하면 CascadeType.REMOVE처럼 동작하게 된다 
-> 만약 Parent 엔티티를 삭제하게 되면 Parent 엔티티 안에 있는 모든 값이 삭제되므로 자연스레 List<Child> 값들도 참조 관계가 끊어지고 삭제가 될 것이기 때문이다.

 

⭐︎ CascadeType.ALL + orphanRemoval = true

- 두 기능을 함께 사용하게 되면 스스로 생명주기를 관리하는 Parent 엔티티 하나로 Child 엔티티도 생명주기를 관리할 수 있게 된다.

- em.persist(parent)로 영속화, em.remove(parent)로 제거가 되기 때문에 Child 스스로 생명주기를 관리하지 않더라도 생명주기를 관리할 수 있게 된다.

728x90

'자바 > JPA' 카테고리의 다른 글

갑 타입 - 임베디드 타입  (0) 2023.08.23
값 타입 - 기본 값  (0) 2023.08.23
지연 로딩과 즉시 로딩  (0) 2023.08.22
프록시  (0) 2023.08.22
실전 예제 - 상속관계 매핑  (0) 2023.08.21