Spring JPA[CASCADE]
CASCADE
CASCADE란?
Cascade는 부모 객체의 상태 변화가 자식 객체에 영향을 주는 것을 말합니다.
즉, 부모 엔티티의 변경이 자식 엔티티에 자동으로 전파됩니다.
부모 엔티티의 상태가 변경되면 해당 변경이 자식 엔티티에 반영되는 것입니다.
이는 부모-자식 관계의 데이터 일관성을 유지하기 위한 중요한 메커니즘 중 하나입니다.
CASCADE 옵션 종류
ALL
- 모든 작업에 대해 cascade를 적용합니다.
- 부모 엔티티의 변경 작업이 자식 엔티티에 전파됩니다.
PERSIST
- 영속성 컨텍스트에 새로운 엔티티를 저장 시, cascade를 적용합니다.
REMOVE
- 엔티티 삭제 시, cascade를 적용합니다.
- 부모 엔티티를 삭제 시, 자식 엔티티도 삭제됩니다.
MERGE
- 엔티티의 변경 사항을 병합할 때 cascade를 적용합니다.
- 부모 엔티티가 병합되면 자식 엔티티도 함께 병합됩니다.
REFRESH
- 엔티티를 리프레시할 때 cascade를 적용합니다.
- 부모 엔티티가 리프레시되면 자식 엔티티도 함께 리프레시 됩니다.
DETACH
- 엔티티 분리 시, cascade를 적용합니다.
- 부모 엔티티가 분리되면 자식 엔티티도 분리됩니다.
이처럼 Cascade에는 여러 종류가 있는데, 이를 사용하기 전에 주의할 점이 있습니다.
주의점
영속성 전이는 연관관계를 매핑하는 것과 아무런 관련이 없습니다. 영속성 전이는 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 편리함을 제공할 뿐입니다.
그리고 영속성 전이를 사용할 때는 주의점이 하나 더 있습니다.
부모와 자식 엔티티가 종속적인 경우에는 영속성 전이를 설정해도 문제가 없지만, 종속적이지 않고 다른 곳에서도 사용되고 있는 경우에는 주의해야 합니다.
예를 들어, 부모 엔티티가 삭제될 때 자식 엔티티도 함께 삭제되도록 설정(CascadeType.REMOVE
)되어 있다면, 자식 엔티티가 다른 곳에서도 사용되고 있을 경우 의도치 않은 데이터 손실이 발생할 수 있습니다.
고아 객체
고아 객체는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 말합니다.
한마디로 부모 객체를 제거하면, 이와 연관되어 있는 자식 객체는 부모 객체와 끊어진 상태가 됩니다. 이런 객체를 고아 객체라고 합니다.
고아 객체 제거
고아 객체 제거 기능을 활성화하면 부모를 제거할 때 자식도 함께 제거가 됩니다.
예제 코드
Author.class
1
2
3
4
5
6
7
8
9
10
11
@Entity
public class Author {
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "author", fetch = FetchType.LAZY,
cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<Book> books;
}
Book.class
1
2
3
4
5
6
7
8
9
10
11
@Entity
public class Book {
@Id
private Long id;
private String title;
@ManyToOne
@JoinColumn(name = "author_id")
private Author author;
}
이렇게 cascade = CascadeType.PERSIST, orphanRemoval = true 이 두가지 옵션을 사용하면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있습니다.
그러나 고아객체를 삭제할때는 주의점있습니다.
주의점
고아 객체 제거 기능은 특정 엔티티가 개인이 소유할 때만 사용해야 합니다. 즉, 참조가 하나일 때만 사용해야 합니다. 여러 곳에서 참조하고 있는 경우, 고아 객체 제거 기능을 사용하면 의도치 않은 데이터 손실이 발생할 수 있습니다.
결론
Cascade는 부모-자식 엔티티 간의 상호작용을 간편하게 관리하는데 도움을 줍니다.모든 변경 작업을 자식 엔티티에게 전파하는 CascadeType.ALL을 선택하는 것이 일반적입니다. 그러나 상황에 따라 필요한 경우에는 다른 옵션을 선택할 수도 있습니다.
고아 객체를 처리할 때에는 주의가 필요합니다. 참조가 끊긴 엔티티는 다른 곳에서 더 이상 참조하지 않는 “고아 객체”로 간주되어야 합니다. 이때, 참조가 한 곳일 때만 사용하고 해당 엔티티가 개인적으로 소유해야 합니다. 만약 참조가 여러 곳이라면 다른 연관된 객체에도 영향을 줄 수 있으므로 주의가 필요합니다.