해당 글은 김영한 님의 자바 ORM 표준 JPA 프로그래밍을 참고하여 작성한 글입니다.
✅ 영속성 전이: CASCADE
- 영속성 전이(transitive persistence): 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 사용한다.
- 설정 방법: @OneToMany(mappedBy = "", cascade = CascadeType.PERSIST)
- 예: 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장할 때
▶ 영속성 전이: 저장
🔽 영속성 전이 설정 코드
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
//영속성 전이, CASCADE 옵션 적용
@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
private List<Child> childList = new ArrayList<>();
...
}
▶ 영속성 전이 주의 사항
- 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없다.
- Entity를 영속화할 때 연관된 Entity도 함께 영속화하는 편리함을 제공할 뿐이다.
- 자식 부모가 하나일 때, 단일 Entity에 완전히 종속적이고 라이프 사이클이 같을 때만 사용한다.
- 예: 게시판, 첨부파일 경로, 글쓴이 계정이 없어지면 해당 게시글이 사라질 때 등
- 다른 Entity에서도 관리하는 자식이라면 사용하면 안 된다.
- 삭제했다가 다른 Entity도 함께 삭제될 수도 있기 때문이다.
▶ CASCADE의 종류
- CascadeType.ALL: 모두 적용
- 라이프 사이클이 완전히 일치할 때 사용해야 한다.
- CascadeType.PERSIST: 영속
- CascadeType.REMOVE: 삭제
- CascadeType.MERGE: 병합
- CascadeType.REFRESH
- CascadeType.DETACH
✅ 고아 객체(ORPHAN)
- 고아 객체: 부모 Entity와 연관관계가 끊어진 자식 Entity
- 고아 객체 제거: JPA가 제공하는 부모 Entity와 연관관계가 끊어진 자식 Entity를 자동으로 삭제하는 기능. 부모 Entity의 컬렉션에서 자식 Entity의 참조만 제거하면 자식 엔티티가 자동으로 삭제된다.
- 설정 방법: @OneToMany(mappedBy = "", orphanRemoval = true)
🔽 고아 객체 제거 설정 코드
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
//고아 객체 제거
@OneToMany(mappedBy = "parent", orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
...
}
🔽 고아 객체 제거 사용 코드
Parent parent = em.find(Parent.class, id);
parent.getChildren().remove(0); //자식 Entity를 컬렉션에서 제거
- 고아 객체 옵션인 orphanRemoval = true를 설정하면 컬렉션에서 제거된 자식 Entity는 자동으로 삭제된다.
- 연관관계를 끊으면 DELETE SQL이 자동으로 실행된다.
▶ 고아 객체 주의 사항
- 참조가 제거된 Entity는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능이다.
- 참조하는 곳이 하나일 때만 사용해야 한다.
- 특정 Entity가 개인 소유할 때만 사용해야 한다.
- @OneToOne, @OneToMany만 사용이 가능하다.
- 개념적으로 부모를 제거하면 자식은 고아 객체가 된다. 따라서 고아 객체 제거 기능을 활성화하면, 부모를 제거할 때 자식도 함께 제거된다. 이것은 CascadeType.REMOVE처럼 동작한다.
✅ 영속성 전이 + 고아 객체, 생명주기
CascadeType.ALL + orphanRemoval = true를 동시에 사용하면 어떻게 될까?
- 일반적으로 Entity는 JPA 영속성 컨텍스트(EntityManager)를 통해 스스로 생명주기를 관리한다.
- em.persist()로 영속화하고, em.remove()로 제거한다.
- 그런데 두 옵션을 모두 활성화할 경우, 부모 Entity를 통해서 자식의 생명주기를 관리할 수 있다.
- 자식을 저장하려면 부모에만 등록하면 된다. (CASCADE)
- 자식을 삭제하려면 부모에서만 제거하면 된다. (orphanRemoval)
- 또한, 도메인 주도 설계(DDD)의 Aggregate Root개념을 구현할 때 유용하다.
📍 참고
'Programming > JPA' 카테고리의 다른 글
[JPA] 값 타입과 불변 객체 - 값 타입 (2) (0) | 2024.07.25 |
---|---|
[JPA] 기본값 타입과 임베디드 타입 - 값 타입 (1) (1) | 2024.07.25 |
[JPA] 즉시 로딩과 지연 로딩 (0) | 2024.07.25 |
[JPA] 프록시 (1) | 2024.07.25 |
[JPA] 고급 매핑(상속관계 매핑) - 엔티티(Entity) 매핑 (7) (0) | 2024.07.25 |