✅ CASCADE 란?
- 특정 엔티티를 영속 상태로 만들 경우, 연관된 엔티티도 함께 영속 상태로 만들고 싶을 경우 영속성 전이를 사용한다. JPA에서는 영속성 전이를 Cascade옵션을 통해서 설정하고 관리할 수 있다.
- 즉, 부모 엔티티를 다룰 경우, 자식 엔티티까지 다룰 수 있다.
💡 영속 상태가 무엇인지 궁금하다면?
https://computerreport.tistory.com/102
[Spring/JPA] 영속성 컨텍스트
✅ 영속성 컨텍스트♐ 영속성 컨텍스트란?Entity 객체를 영속성 상태로 관리하는 일종의 캐시 역할을 하는 공간으로 여기에 저장된 Entity는 데이터베이스와 자동으로 동기화되며 같은 트랜잭션
computerreport.tistory.com
✅ CASCADE 옵션
- ALL
- PERSIST
- MERGE
- REMOVE
- REFRESH
- DETACH
♐ @ CascadeType.PERSIST
- CascadeType.PERSIST로 설정하고 부모인 comment을 영속화했을 경우, commentLikeList에 담긴 commentLike까지 함께 영속화가 된다.
@Getter
@Entity
@NoArgsConstructor
public class Comment extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, columnDefinition = "longtext")
private String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "board_id")
private Board board;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
@OneToMany(mappedBy = "comment",cascade = CascadeType.PERSIST)
private final List<CommentLike> commentLike = new ArrayList<>();
♐ @ CascadeType.REMOVE
- 위에서 영속시킨 comment와 commentLike를 모두 제거할려면 REMOVE를 사용할 수 있다.
Comment comment = EntityManger.find(Comment.class,1L);
EntityManager.remove(comment);
❓ 만약 REMOVE 를 쓰지 않는다면?
- 코드가 굉장히 길어진다.
Comment comment = EntityManger.find(Circle.class,1L);
CommentLike commentLike1 = EntityManager.find(CommentLike.class,1L);
CommentLike commentLike2 = EntityManager.find(CommentLike.class,2L);
EntityManager.remove(commentLike1);
EntityManager.remove(commentLike2);
EntityManager.remove(comment);
♐ @ CascadeType.ALL
- @ CascadeType.PERSIST 와 @ CascadeType.REMOVE 모두 수행해준다.
♐ CF) CascadeType.Remove vs. orphanRemoval = true
부모 엔티티에서 자식 엔티티와의 연관관계를 제거하는 경우
- a) CascadeType.Remove 옵션은 참조를 변경시켜서 무결성 오류를 안나게 할 뿐 데이터는 남아있게 된다. 즉,자식객체가 그대로 남아있다.
- b) orphanRemoval=true 옵션은 부모 객체와의 연관관계가 끊어지면 고아객체가 되고, 고아객체를 자동으로 삭제해주는 옵션.
✅ CASCADE Type 옵션을 사용할 때 고려해야 할 점
- 양방향 관계 - Comment가 Board 와 Users 대한 참조를 가지고 있기 때문에, 어떤 쪽에서 부모 엔티티를 삭제하거나 연관 관계를 변경할 때, 자식 엔티티인 Comment 가 어떻게 영향을 받을지에 생각해봐야 한다.
@Entity
class Board{
@OneToMany(mappedBy = "Board", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserBoard> userBoardList;
}
@Entity
class Users{
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> CommentList;
}
@Entity
class Comment{
@ManyToOne(fetch = FetchType.LAZY)
private Board Board;
@ManyToOne(fetch = FetchType.LAZY)
private Users users;
}
상황
1️⃣ 만약 Board 에 있는 Comment (댓글) 의 기록을 남기고 싶지만 Users 를 삭제한다면?
- Users 를 삭제하면 연관관계가 맺어져있는 자식인 Comment 도 삭제되버린다.
즉, Cascade 옵션을 사용할 경우 완전히 개인소유하지 않는다면 경계를 하며 사용해야한다.
✅ 정리
1️⃣ CascadeType.PERSIST:
- 부모 엔티티 저장 시 자식 엔티티도 함께 저장.
예외: 자식이 이미 DB에 존재하면 detached entity passed to persist 발생.
2️⃣CascadeType.MERGE:
- 부모 엔티티가 merge()될 때, detached 상태의 자식 엔티티 변경 사항 적용.
3️⃣CascadeType.REMOVE:
- 부모 엔티티 삭제 시 자식 엔티티도 함께 삭제.
차이점: orphanRemoval은 자식의 관계가 끊어질 때 삭제.
4️⃣CascadeType.DETACH:
- 부모 엔티티가 detach()될 때, 자식 엔티티도 detach 상태로 변경.
5️⃣CascadeType.ALL:
- 모든 Cascade 옵션 적용 (PERSIST, MERGE, REMOVE, DETACH 등).
'Spring' 카테고리의 다른 글
[Spring]Converter 보다 세부적으로 타입변경하는 법 (0) | 2025.04.16 |
---|---|
[Spring]HttpMessageConverter (0) | 2025.04.16 |
[Spring/JPA] 영속성 컨텍스트 (0) | 2025.04.11 |
[Spring] Annotation (2) | 2025.04.10 |
[Spring] Controller 와 RestContoller 의 차이 (0) | 2025.04.10 |