본문 바로가기
[Spring Boot]/[JPA]

[JPA] 영속성 전이

by 북방바다코끼리표범 2023. 10. 27.

복습

https://shins99.tistory.com/115

 

[JPA] 상속관계 매핑

복습 https://shins99.tistory.com/114 [JPA] 연관관계 매핑 정리 복습 https://shins99.tistory.com/113 [JPA] 양방향과 단방향 매핑, 연관관계의 주인(mappedBy) 복습 http://shins99.tistory.com/112 [JPA] 기본 키(primary key)와 매

shins99.tistory.com


영속성 전이

- 부모 엔티티의 생명주기에 종속적인 자식 엔티티의 상태변화를 같이 처리하는 역할

(부모 엔티티를 저장하거나 삭제 할 때,자식 엔티티 역시 같이 저장하거나 삭제)

- 자식 엔티티를 추가적으로 저장, 삭제하기 위한 코드를 작성하지 않아도 된다는 장점

( 연관관계를 매핑하는 것 과는 관련 없음)

 

 

사용방법

- 영속성 전이는 @OneToOne, @OneToMany, @, @ManyToMany 관계에서 사용가능

- 사용하는 연관관계 매핑 옵션에 cascade = CascadeType.XXX과 같은 옵션을 설정하여 사용가능

 

주로 사용하는 옵션

  • CascadeType.ALL - 아래의 모든 CascadeType을 적용
  • CascadeType.PERSIST - 부모 엔티티를 저장할 때 연관된 자식 엔티티도 함께 저장 (부모와 자식 영속 상태 )
  • CascadeType.REMOVE - 부모 엔티티를 삭제할 때 연관된 자식 엔티티들도 함께 삭제

 

1 : N 의 양방향 관계를 갖는 Parent와 Child의 코드

 
@Entity
 
public class Parent {
 
 
 
@Id
 
@GeneratedValue
 
private Long id;
 
 
 
private String name;
 
 
 
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
 
private List<Child> childs = new ArrayList<>();
 
 
 
// 양방향 매핑을 위한 편의 함수
 
public void addChild(Child child) {
 
childs.add(child);
 
child.setParent(this);
 
}
 
...
 
}

 
@Entity
 
public class Child {
 
 
 
@Id
 
@GeneratedValue
 
private Long id;
 
 
 
private String name;
 
 
 
@ManyToOne
 
@JoinColumn(name = "parent_id")
 
private Parent parent;
 
...
 
}

 

- Parent와 Child는 1 : N의 관계이므로 하나의 Parent는 여러 Child를 가질 수 있음

- 2개의 Child를 갖는다면 다음과 같이 persist()를 3번 호출해 Parent와 Child 각각 영속화를 시켜야 함

- 영속화 전이 "cascade"를 사용하면 Parent만 persist()로 영속화를 하여도 자식도 영속화 가능

 
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);

 

저장 결과

 

Parent에 아래의 영속화 옵션을 추가

 
@Entity
 
public class Parent {
 
...
 
 
 
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
 
private List<Child> childs = new ArrayList<>();
 
 
 
...
 
}

 

이번엔 Parent 엔티티만 persist() 했음에도 똑같은 결과가 나옴

 
Child child1 = new Child("김하늘");
 
Child child2 = new Child("김별");
 
 
 
Parent parent = new Parent("김부모");
 
parent.addChild(child1);
 
parent.addChild(child2);
 
 
 
em.persist(parent);

어디에 cascade를 어디서 설정하는가?

- cascade는 부모 - 자식 관계에서 부모이거나, 연관관계의 주인이 아닌 반대편에 설정


cascade를 사용하는 경우

 부모 엔티티와 자식 엔티티 간의 라이프사이클이 같을 시

- 부모 엔티티와 자식 엔티티의 상태 변화가 서로에게 영향을 주는 경우, cascade 옵션을 사용하여 상태 변화를 전파 가능(데이터의 일관성을 유지하고 코드의 중복을 줄여줌)

 

엔티티 간의 종속성이 큰 경우

- 엔티티 간의 종속성이 크다면, 한 엔티티의 상태 변화가 다른 엔티티에 영향을 미칠 가능성이 높음

(cascade 옵션을 사용하여 상태 변화를 자동으로 전파하도록 설정가능)

 

많은 엔티티에 영향을 미치는 경우, 성능 저하의 원인

- cascade 옵션은 신중하게 사용해야 하며, 꼭 필요한 경우에만 설정하는것을 추천