본문 바로가기
JPA

JPA - 영속성 전이(CASCADE)와 고아 객체

by 왈레 2022. 4. 11.

1. 영속성 전이(CASCADE)

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

ex) 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장

 

 

※ 참고로 영속성 전이(CASCADE)는 연관관계나, 즉시로딩(지연로딩)과 전혀 관계가 없다.

※ 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함 을 제공할 뿐이다.

 

 

영속성 전이: 저장

 

public class Parent{
    ...
    
    @OneToMany(mappyBy = "parent", cascade = CascadeType.ALL)
    private List<Child> childList = new ArrayList<>();
    
    public void addChild(child child){
       childList.add(child);
       child.setParent(this);
       //실제로 연관관계 편의 메서드는 이보다 좀더 복잡함
    }
}

public class Child{
    ...
    
    @ManyToOne
    @JoinColumn(name = "parent_id")
    private Parent parent;
}

main{
    try{
        Child child1 = new Child();
        Child child2 = new Child();
        
        Parent parent = new Parent();
        parent.addChild(child1);
        parent.addChild(child2);
        
        em.persist(parent);
    }
}

 

CASCADE의 종류

  • ALL: 모두 적용 (저장, 삭제 등등 라이프 사이클을 전부 맞춰야할 때)
  • PERSIST: 영속 (저장 할때만)
  • REMOVE: 삭제 (삭제 할때만)
  • MERGE: 병합
  • REFRESH: REFRESH
  • DETACH: DETACH

 

영속성 전이: CASCADE - 주의점

 

CASCADE를 사용할 수 있는 2가지 조건

  1. parent와 child의 라이프 사이클이 동일하거나 유사할 때
  2. 단일 소유자일 경우 (오직 parent만이 child를 소유할 때, 다른 Entity가 child를 소유해서는 안됨)

오직 하나의 parent가 child를 관리하는 거라면 CASCADE를 사용해도 상관없다.

그런데 child가 다른 Entity와 연관관계를 맺고 관리되고 있다면 절대 사용하면 안된다.

 

 

CASCADE를 사용하기 좋은 케이스

ex) 게시판이 첨부파일을 포함하는 관계

 

2. 고아 객체

• 고아 객체 제거: 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제

• 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 판단하고 삭제하는 기능

orphanRemoval = true

 

public class Parent{
    ...
    
    @OneToMany(mappyBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Child> childList = new ArrayList<>();
}

main{
    Parent findParent = em.find(Parent.class, parent.getId());
    findParent.getChildList().remove(0);
}

 

Parent 객체에서 관리되는 컬렉션(childList)에서 제거가 되면 DB에서도 삭제가 된다.

 

 

고아 객체 - 주의

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

 

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

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

※출처 - 인프런 김영한 JPA

'JPA' 카테고리의 다른 글

JPA - 값 타입과 불변 객체  (0) 2022.04.12
JPA - 기본값 타입과 임베디드 타입  (0) 2022.04.12
JPA - 즉시 로딩과 지연 로딩  (0) 2022.04.11
JPA - 프록시  (0) 2022.04.11
JPA - @MappedSuperclass  (0) 2022.04.10

댓글