오봉이와 함께하는 개발 블로그
JPA - 영속성 전이(CASCADE)와 고아 객체 본문
728x90
영속성 전이(CASCADE)
즉시 로딩, 지연 로딩과는 전혀 관련 없는 개념이다.
특정 엔티티를 영속 상태로 만들 때 연관된 다른 엔티티도 함께 영속 상태로 만들고 싶을 때 사용한다.
예를 들어 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장할 경우 영속성 전이를 사용하면 편리하다.
@OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST)
예제 코드
@Entity
@Getter @Setter
public class Parent {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent")
private List<Child> childList = new ArrayList<>();
public void addChild(Child child) {
childList.add(child);
child.setParent(this);
}
@Entity
@Getter @Setter
public class Child {
@Id @GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
// 메인 메소드
Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);
em.persist(parent);
위와 같이 코드를 작성하면 parent만 영속화 되어 쿼리가 날아가지 child에 대한 내용은 아무 것도 아닌 것이 된다.
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> childList = new ArrayList<>();
위와 같이 코드를 바꿔준다면 child에 대한 내용은 persist를 하지 않아도 parent를 따라 자동으로 영속화 되어 쿼리가 날아가고 DB에 값이 저장된다.
주의
- 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없다.
- 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함을 제공할 뿐이다.
- 라이프 타임이 같을 때 사용하자.
- 하위 클래스가 가진 부모 클래스가 한 개일 때를 제외하면(단일 소유자가 아닐 때) 사용하지 말자.
- 원하지 않게 데이터에 변경이 일어날 수 있다.
CASCADE의 종류
- ALL : 모두 적용
- PERSIST : 영속(저장할 때)
- REMOVE : 삭제
- MERGE : 병합
- REFRESH : REFERESH
- DETACH : DETACH
보통은 ALL 혹은 PERSIST를 주로 사용한다.
고아 객체
부모 엔티티와 연관관계가 끊어진 자식 엔티티를 고아 객체라 한다.
고아 객체 제거를 제거하는 옵션은 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제한다.
- orphanRemoval = true
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
Parent parent1 = em.find(Parent.class, id);
parent1.getChildren().remove(0);
//자식 엔티티를 컬렉션에서 제거
- 결과 : DELETE FROM CHILD WHERE ID=?
주의
- 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 간주하고 삭제하는 기능
- 영속성 전이와 마찬가지로 참조하는 곳이 하나일 때 사용해야 한다.
- 영속성 전이와 마찬가지로 특정 엔티티가 개인 소유일 때 사용해야 한다.
- @OneToOne, @OneToMany만 사용 가능함.
- 개념적으로 부모를 제거하면 자식은 고아가 되기 때문에 orphanRemoval 기능을 활성화 하면 자식도 함께 제거됨
- CascadeType.REMOVE처럼 동작한다.
영속성 전이 + 고아 객체, 생명주기
- CascadeType.ALL + orphanRemovel=true
스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove()로 제거한다.
두 옵션을 모두 활성화 하면 부모 엔티티를 통해 자식 엔티티의 생명주기를 관리할 수 있다.
도메인 주도 설계(DDD)의 Aggregate Root 개념을 구현할 때 유용하다.
출처 : 인프런 김영한 지식공유자님의 스프링 부트와 JPA 실무 완전 정복 로드맵 강의
728x90
'BE > JPA' 카테고리의 다른 글
JPA - 기본값 타입 (0) | 2022.06.29 |
---|---|
JPA - 실전 예제 5 - 연관관계 관리 (0) | 2022.06.28 |
JPA - 즉시 로딩, 지연 로딩 (0) | 2022.06.28 |
JPA - 프록시 (0) | 2022.06.28 |
JPA - 실전 예제 4 - 상속관계 매핑 (0) | 2022.06.28 |
Comments