만약에 Parent - Child 는 양방향 연관관계로 되어 있고,. Child 테이블이 외래키를 관리하는 주 테이블이라고 하자.
여기서 이 두개의 인스턴스를 모두 영속화 하기 위해서는 em.persist()를 최소 2번은 호출하여야 각각 모두 영속화가 된다.
여기서 드는 의문점은 다음과 같다.
Parent가 관리하는 Child 인스턴스의 경우 Parent를 em.persist() 할 때 같이 진행하면 편하지 않을까?
이러한 질문을 해결할 수 있는 옵션이 바로 cascade 영속성 전이 이다.
✅ cascade의 종류
- All
- Persist
- Remove
- Merge
- Refresh
- Detach
주로 사용하게 되는 것은 All 또는 Persist 이다.
위의 종류에 대한 자세한 설명은 후속편으로 깊이 있기 공부해 보려고 한다.
주로 사용하게 되는
All : 모든 영속성이 전이 된다.
Persist : 엔티티가 저장될 때, 연쇄적으로 저장되게 하는 옵션이다.
🤔 cascade는 어디에다 써야 될까 ?
일대다 연관 관계 기준, 연관관계의 주인은 항상 다에 존재한다고 알고 있을 것이다.
cascade는 다 ( N )의 반대 즉 일 ( 1 )에 사용해주면 된다.
위와 같이 써야 하는 이유에 대하여 생각해 보았다.
예를들어, 현재 프로젝트에서 사용장인 숙소와 룸에 대해 생각해 보면
Accommodation (숙소) 1 - N (룸) Room [양방향 연관관계]
만약, 각각의 경우에 cascade 속성을 넣어준다고 가정해보면!
@ManyToOne(CascadeType.ALL)
- 방이 삭제되면 숙소도 삭제 된다.
@OneToMany(CascadeType.ALL)
- 숙소가 삭제되면 룸도 삭제된다.
- 숙소를 추가할 때, 룸도 추가된다.
이렇게 됬을 때, N 관계에서 cascade을 사용하면 숙소 즉, 부모를 잃어버리는 룸(자식) 들이 발생하게 되고
이를 고아 객체라고 한다.
이러한 이유로 1관계에 cascade 옵션을 사용하는게 맞으며,
@OneToOne 관계에서도 상호 관계에 따라 알맞은 위치에 써야 한다.
📌 현재 프로젝트에 적용해 보자 !
현재 프로젝트에서 OneToOne 관계인 리뷰와 답글(리뷰에 대한)에 대해 cascade 속성을 생각해보면
답글이 달른 게시글을 삭제할 경우, 답글도 모두 삭제가 되버린다.
이 경우, 유저는 본인이 쓴 답글을 확인 할 수 없게 된다 ...
반대로 답글을 삭제할 때, 댓글이 삭제된다.
이 경우는 말도 안된다...
그래서 리뷰와 답글 관계에서는 cascade 옵션을 사용하지 않기로 결정하였다.
📚 위에서 말했듯이 cascade에 대한 이론은 깊고 방대하므로, 추후 깊게 공부한 게시글을 업로드 해보도록 하겠다!
'토이 프로젝트 배우게 된 것들 & 오류 해결🐰' 카테고리의 다른 글
Unit Test 작성의 필요성 (0) | 2023.02.01 |
---|---|
JPA | @Transactional 과 변경감지 (0) | 2023.01.30 |
JPA | QueryDsl orderBy(정렬) 동적으로 사용하는 방법 (0) | 2023.01.21 |
Querydsl | Pageable과 page를 사용하는 방법 (2) | 2023.01.11 |
JPA | QueryDsl 집계함수[SUM, COUNT ..] 사용 시, Dto로 반환 (0) | 2023.01.04 |