개발자꿈나무
영속성 전이, 고아 객체 본문
★ 영속성 전이 : 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 스스로 생명주기를 관리하지 않더라도 생명주기를 관리할 수 있게 된다.
'자바 > JPA' 카테고리의 다른 글
갑 타입 - 임베디드 타입 (0) | 2023.08.23 |
---|---|
값 타입 - 기본 값 (0) | 2023.08.23 |
지연 로딩과 즉시 로딩 (0) | 2023.08.22 |
프록시 (0) | 2023.08.22 |
실전 예제 - 상속관계 매핑 (0) | 2023.08.21 |