스프링 부트/JPA
[JPA] Cascade 간단 노트
newwisdom
2021. 8. 14. 15:56
반응형
2021-07-08글
JPA에서 엔티티를 저장할 때 연관된 모든 엔티티는 영속 상태여야 한다.
부모 엔티티를 영속 상태로 만들 때 연관된 자식도 한번에 영속 상태로 만들 수 있다.
Cascade란?
- 영속성 전이
- 연관관계에 있는 엔티티에 작업이 이루어져 상태 변화가 이뤄질 시 동일한 작업이 연결된 엔티티에 전이되는 옵션
- 일반적으로 부모 엔티티에서 cascade 옵션을 걸어줌
- 자식에서 부모로 옵션을 거는 것은 의미가 없다고함
- 즉시로딩, 지연로딩, 연관관계 세팅과 관계 없음
- 부모, 자식 엔티티와 연관관계 주인(외래키 관리자)는 다름
Entity의 상태
- Transient : JPA가 모르는 상태 (단순 객체 생성)
- Persistent : JPA가 관리중인 상태 (1차 캐시, Dirty Checking, Write Behind, ...)
- Detached : JPA가 더이상 관리하지 않는 상태
- Removed : JPA가 관리하긴 하지만 삭제하기로 한 상태
casecade 옵션 (일부)
PERSIST
- 엔티티를 영속화 할 때 연관된 엔티티도 함께 유지
- Transient 인스턴스를 Persistent로 만들어줌
REMOVE
- 엔티티를 삭제할 때, 연관된 엔티도 함께 삭제
ALL
- 모든 CASCADE 옵션 적용
- 모든 작업을 부모에서 자식 엔티티로 전파
예시
아무런 옵션이 없는 경우
Comment
@Entity
public class Comment {
@Id
@GeneratedValue
private Long id;
private String comment;
@ManyToOne
private Post post;
}
Post
@Entity
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(mappedBy = "post")
private Set<Comment> comments = new HashSet<>();
public void addComment(Comment comment) {
this.getComments().add(comment);
comment.setPost(this);
}
}
Test 코드
- 자식인 Comment는 저장되지 않음
- id가 null임을 확인
CascadeType.ALL을 건 경우
- 부모인 Post 엔티티에서 자식인 Comments에 옵션걸기
- id가 null이 아님을 확인
고아 객체 제거
- JPA에서는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능 제공
- 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제
- 때문에 참조하는 객체가 하나일 때만 사용해야 함 (특정 엔티티에서만 소유하고 있는 엔티티)
@OneToOne
,@OneToMany
에서만 사용 가능
Example
- Comments 객체는 Post에서만 소유하고 있음
- Comments에
orphanRemoval
옵션 추가
- Comments를 제거하였을 때,
- comment에 대해서 다음과 같이 delete 쿼리가 나감
참고 자료
반응형