지나공 : 지식을 나누는 공간

JPA 6 : 영속성 전이(CASCADE)란? 본문

Tech/JPA

JPA 6 : 영속성 전이(CASCADE)란?

해리리_ 2020. 11. 1. 14:44

이번 포스팅에서 공부할 내용은!

->영속성 전이 (CASCADE) : 정의, 주의점, 종류

 

->고아 객체 : 정의, 주의

 

-> (영속성 전이 + 고아 객체)와 생명주기

영속성 전이란? (CASCADE)

 

특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶은 경우에 사용합니다.

 

예를 들어 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장하거나, 부모 엔티티를 삭제할 때 관련된 자식엔티티도 함께 삭제하고 싶을 때 사용합니다.

 

영속성 전이 : 저장 (PERSIST)

 

아래의 예시를 봅시다. 현재 Parent와 Child는 1:N 연관관계 (@OneToMany, @ManyToOne 사용)를 가진 상태입니다.

public class JpaMain(){
	public static void main(String[] args){
    	
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();
        
        EntityTransaction tx = em.getTransaction;
        tx.begin();
        
        try{
			Child child1 = new Child();
			Child child2 = new Child();

			Parent parent = new Parent();
			parent.addChild(child1);
			parent.addChild(child2);

			em.persist(parent);
			em.persist(child1);
			em.persist(child2);
            
            tx.commit();
        }catch(Exception e){
        	tx.rollback();
        }
    }
}

 

위의 코드대로라면 persist 상태로 세 객체를 만들기 위해서 persist()를 세 번 호출해야 합니다.

이런 것이 번거롭기 때문에 우리는 parent객체 하나만으로 child1, child2를 같이 관리하고 싶은 겁니다.

parent하나만 persist 상태로 만들면 이것과 연관관계를 가진 child1, child2가 자동으로 persist가 되도록요.

 

이때 사용하는 것이 바로 CASCADE 입니다.

 

이 상태에서 parent만 persist를 하면 child1, child2가 같이 persist가 됩니다.

 

영속성 전이 주의점! (CASCADE 사용 시)

 

-> 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없습니다.

엔티티를 영속화 할 때 연관된 엔티티도 함께 영속화하는 편리함을 제공할 뿐이고, 연관관계 매핑과는 무관합니다.


-> 사용하는 두 객체의 라이프사이클이 거의 동일할 때, 그리고 소유되는 연관관계가 하나(단일소유자)일 때 사용합니다. 

예를 들어 위의 코드에서 Parent만 Child를 소유하고 있는 상태인데 Member도 Child를 소유하는 상황이라면 이걸 쓰면 안됩니다. 단일 엔티티에 완전히 종속적일 때는 보통 라이프사이클이 똑같아서 cascade를 사용해도 좋지만 그런게 아니라면 사용하지 않는 게 좋습니다.

 

CASCADE 의 종류 (검은 색 위주로 사용)

 

-> ALL : 모두 적용 

-> PERSIST : 영속 (딱 저장할 때만 life cycle을 맞춰야 하는 경우)

-> REMOVE : 삭제

-> MERGE : 병합

-> REFRESH : REFRESH

-> DETACH : DETACH

 

고아 객체

 

부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제할 때 사용하는 것으로, 고아 객체 말 그대로

부모와 연관관계가 끊어진 고아 객체라는 말이다.


-> 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능입니다.

 

-> orphanRemoval = true

 

위의 코드처럼 orphanRemoval을 설정한 상태에서 부모의 연관되는 child List중 어떤 child를 지운 뒤 실행하면

Parent findParent = em.find(Parent.class, parent.getId());

findParent.getChildList().remove(0); // 첫 번째 자식객체를 지움

저 자식객체에 대해 delete 쿼리문이 실행됩니다. -> DELETE FROM CHILD WHERE ID = ? 

즉, ophanRemoval을 true로 하면 연관관계가 있는 객체들의 컬렉션에서 어떤 객체를 뺐을 때 그 객체를 자동으로 DB에서도 삭제합니다.

 

 

고아 객체 주의점! ( 영속성 전이와 비슷)

 


-> 참조하는 곳이 하나일 때 사용해야 합니다.


-> 특정 엔티티가 개인소유할 때 사용해야 합니다.

 

-> @OneToOne, @OneToMany만 사용 가능합니다.

-> 개념적으로 부모를 제거하면 자식은 고아가 됩니다. 따라서 고아 객체 제거 기능을 활성화하면, 마치 cascade 타입을 REMOVE로 한 것과 같이, 부모를 제거할 때 자식도 함께 제거됩니다. 

 

(영속성 전이 + 고아 객체) 와 생명주기


-> CascadeType.ALL + orphanRemoval = true

-> 위의 Parent 객체처럼 스스로 생명주기를 관리하는 엔티티는 EntityManager를 통해서 em.persist(), em.remove() 등의 메소드 호출을 통해 영속화하기도 하고 제거하기도 합니다.

-> 두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있습니다.

(parent객체에 대한 메소드 호출만으로 자식의 생명주기 관리가 가능합니다. 위의 예제들에서 확인했습니다.)


-> 도메인 주도 설계(DDD)의 Aggregate Root 개념을 구현할 때 유용합니다.

 

Aggregate Root 가 뭔지 아래 링크를 통해 확인하세요.

 

eocoding.tistory.com/36

 

DDD, Aggregate Root 란?

이번에 알아볼 것은, DDD란? Domain이란? Domain Model이란? DDD가 필요한 이유 DDD와 Aggregate Root DDD의 특징과 이유 간단히 DDD(Domain Driven Design)란? 도메인 중심으로 설계하는 디자인 방법론 Domain이..

eocoding.tistory.com



본 포스팅은 김영한 님의 자바 ORM 표준 JPA 프로그래밍 - 기본편의 강의를 듣고 정리한 내용입니다.

728x90
Comments