김영한님의 인프런 강의와 PDF를 바탕으로 정리하였습니다.
https://www.inflearn.com/courses?s=%EA%B9%80%EC%98%81%ED%95%9C
영속성 전이 : CASCADE
영속성 전이란
특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때
예: 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장.
아래처럼 Parent와 Child 엔티티를 작성합니다.
Parent
Child
맨 위의 표와 같이 Parent : Child 는 1:N 관계입니다.
아래 코드 처럼 child를 2개 작성하고 하나의 parent의 자식으로 만든 뒤, 생성한 3개의 객체(parent, child1, child2)를 persist하기 위해서는 총 3번의 persist가 필요합니다.
하지만 parent의 childList에 이미 2개의 child가 add된 상태인데 이렇게 3번의 persist를 할 필요가 있을까요?
하여 cascade를 사용할 수 있습니다.
아래는 cascade를 적용한 Parent엔티티입니다.
이래처럼 parent만 persist한 결과를 보시면 parent뿐 아니라 2개의 child까지 insert되었습니다.
Cascade는 부모를 저장할 때 부모와 연관된 객체도 저장합니다.
영속성 전이: CASCADE - 주의!
1. 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없습니다.
2. 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함 을 제공할 뿐
CASCADE의 종류
ALL: 모두 적용
PERSIST: 영속
REMOVE: 삭제
MERGE: 병합
REFRESH: REFRESH DETACH: DETACH
Parent와 child만 연관관계가 있을 때는 써도 되지만 Child가 또 다른 엔티티와 연관관계가 있다면 Parent에 cascade는 쓰지 않는게 좋습니다.
고아객체
고아 객체 제거 : 부모 엔티티와 연관관계가 끊어진 자식 엔티티 를 자동으로 삭제합니다.
orphanRemoval = true
예를 들어 아래와 같은 코드가 있을 때
Parent parent1 = em.find(Parent.class, id);
parent1.getChildren().remove(0); //자식 엔티티를 컬렉션에서 제거
현재 parent의 childList에 있던 0번째 child는 고아 객체입니다.
이러한 고아객체를 자동으로 삭제하기 위해 orphanRemoval = true를 사용합니다.
Parent에 orphanRemoval = true를 적용하고 코드로 보겠습니다.
child1을 삭제하는 코드입니다.
아래 결과를 보시면 컬렉션에서 삭제했을 뿐인데, delete쿼리가 날라갔습니다.
고아 객체 - 주의
- 참조하는 곳이 하나일 때 사용해야함!
- 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능
- 특정 엔티티가 개인 소유할 때 사용
- @OneToOne, @OneToMany만 가능
- 참고: 개념적으로 부모를 제거하면 자식은 고아가 됩니다. 따라서 고아 객체 제거 기능을 활성화 하면, 부모를 제거할 때 자식도 함께 제거됩니다. 이것은 CascadeType.REMOVE처럼 동작합니다.
영속성 전이 + 고아 객체, 생명주기 < CascadeType.ALL + orphanRemovel=true >
1. 스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove()로 제거
(아래 2번의 코드에서 Parent가 스스로 생명주기를 관리하는 엔티티입니다.)
2. 두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있습니다.
즉 아래와 같습니다.
현재 persist도 parent만 했고, remove도 parent에 대해서만 했습니다만 child들도 따라서 persist되고, remove됩니다.
이것이 "부모 엔티티를 통해서 자식의 생명 주기를 관리"한다는 것입니다.
3. 도메인 주도 설계(DDD)의 Aggregate Root개념을 구현할 때 유용
'JPA > JPA원리' 카테고리의 다른 글
22. 값타입 - 기본값 타입, 임베디드 타입, 불변객체, 값타입 컬렉션 (0) | 2021.07.17 |
---|---|
21. 실전예제 적용해보기 (0) | 2021.07.16 |
19. 지연로딩 (0) | 2021.07.16 |
18. 프록시 (0) | 2021.07.15 |
17. @MappedSuperclass (0) | 2021.07.14 |