토이 프로젝트 배우게 된 것들 & 오류 해결🐰

JPA | 일대일 양방향 관계에서 CasCade 옵션 적용 일화 ..?🤔

j_estory 2023. 1. 25. 23:47

만약에 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에 대한 이론은 깊고 방대하므로, 추후 깊게 공부한 게시글을 업로드 해보도록 하겠다!