영속성 전이(CASCADE) + 고아객체

D A S H B O A R D
D E V E L O P
S E C U R I T Y
 영속성 전이 : CASCADE
 CASCADE의 종류
 CASCADE 예시
 고아객체
 고아객체 예시
Reference

 주의!!!!

CASCADE와 고아 객체는 반드시 참조하는 곳이 하나일 때 사용해야한다!!!
예를 들어, Child 객체를 참조하는 곳이 Parent 밖에 없다면 사용 가능하다. 하지만 Child를 참조하는 곳이 Parent와 Member 두곳이면? 사용하면 절대로 안된다!!!!

 영속성 전이 : CASCADE

영속성 전이(CASCADE)는 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들도 싶을 때 사용되는 기능이다.
예 : 부모 엔티티가 삭제되었을 때, 이와 연관된 자식 엔티티도 함께 삭제
예: 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장
주의!!!
영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없음
엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함을 제공할 뿐

 CASCADE의 종류

ALL : 모두 적용
@OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
PERSIST : 영속
@OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST)
REMOVE : 삭제
@OneToMany(mappedBy="parent", cascade=CascadeType.REMOVE)
MERGE : 병합
REFRESH : REFRESH
DETACH : DETACH

 CASCADE 예시

Child child1 = new Child(); Child child2 = new Child(); Parent parent = new Paren(); parent.addChild(child1); parent.addChild(child2); em.persist(parent);
Java
복사
위와 같은 코드를 짯을 때 원래라면 Parent 테이블에만 쿼리가 날라가야한다.
하지만, CASCADE를 ALL 혹은 Persist로 설정했다면, Child 테이블에도 쿼리가 날라가 Parent와 Child 모두 저장하게 된다.

 고아객체

고아 객체란, 부모-자식 관계에서 부모 엔티티와 연관된 자식 엔티티가 더 이상 참조되지 않으면 자동으로 삭제되는 기능입니다. 이를 통해 더 이상 필요하지 않은 엔티티를 자동으로 삭제할 수 있습니다.
예를 들어, 부모 엔티티에서 자식 엔티티를 제거하고 부모 엔티티를 저장할 때 고아 객체가 활성화되어 있다면, 자식 엔티티가 자동으로 삭제됩니다. 이를 위해 orphanRemoval = true 속성을 @OneToMany 어노테이션에 추가해주면 됩니다.
@OneToMany(mappedBy="parent",orphanRemoval = true)
주의
참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능
참조하는 곳이 하나일 때 사용해야함!
특정 엔티티가 개인 소유할 때 사용
@OneToOne, @OneToMany만 가능
참고: 개념적으로 부모를 제거하면 자식은 고아가 된다. 따라서 고아 객체 제거 기능을 활성화 하면, 부모를 제거할 때 자식도 함께 제거된다. 이것은 CascadeType.REMOVE처럼 동작한다.
만약 영속성 전이 + 고아 객체 둘을 모두 사용한다면?
@OneToMany(mappedBy="parent",cascade=CascadeType.ALL, orphanRemoval = true)
스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove()로 제거
두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있음
도메인 주도 설계(DDD)의 Aggregate Root개념을 구현할 때 유용

 고아객체 예시

Parent parent1 = em.find(Parent.class, id); parent1.getChildren().remove(0);
Java
복사
위 코드에 따르면 자식 엔티티가 제거되게 되면서 더 이상 참조되지 않는다.
따라서 DELETE FROM CHILD WHERE ID=? 라는 삭제 쿼리가 날라가게 된다.