먼저 도메인 모델을 보자.
Category 에서는 CategoryStore를 일대다로 참조하고 있으며,
Store 에서는 CategoryStore를 일대다로 참조하고 있다.
또한 Store 에서는 categoryStoreList를 cascade = CascadeType.ALL 옵션을 주었다.
왜?? 만약 가게 사라진다면 가게와 연결해 있던 카테고리들을 모두 삭제해야하기 때문이다.
예시 데이터를 먼저 넣어보자. 여기서 "연우김밥"가게를 삭제해보자.
그러면 어떻게 될까??
원하는 대로 잘 된다!
다시 원상 복귀하자.
그렇다면 여기서 김밥이라는 카테고리를 삭제하면
김밥을 참조하고있는 categoryStore도 삭제해야 될 것이다.
그래서 카테고리에 아래처럼 해주고 "김밥"을 삭제하면
category_store는 1개의 로우만 남고 김밥은 정상적으로 삭제가 될까?
결과는 "무결성 제약 조건에 위배되어 쿼리를 실행할 수 없다고 한다 "
또한 Store를 삭제하면 어떻게 될까?
아까는 Store 삭제 잘되었는데?
문제는 여기있다. cacade = CascadeType.ALL 을 제거하면 된다.
제거하면 Store는 삭제가 잘되며 category는 참조하고 있는 categoryStore가 없을 경우에만 삭제가 가능하다.
왜 이런일이 일어날까?? 차례로 분석해본다.
1) Category 에서 categoryStoreList 를 cascade = CascadeType.ALL 을 설정했을 경우
만약 Store 한개를 삭제하려고 하면
Store를 참조하고 있는 CategoryStore 가 있다.
하지만 CategoryStore는 Category 에서 cascade = CascadeType.ALL로 참조하고 있으므로 만약 Store를 삭제하게 될 경우 categoryStore를 삭제한다면 Category입장에서는 categoryStore를 전적으로 소유하고 있는 마당에 내 소유물을 맘대로 지울수 있냐는 것이다. 그래서 데이터 무결성에 어긋날수 있다고 경고하는 것이다.
2) " Category 에서 categoryStoreList를 cascade = CascadeType.ALL 설정하고 Store 에서 categoryStoreList 의 cascadeType.ALL을 제거 VS Category 에서 categoryStoreList를 cascade = CascadeType.ALL 제거하고 Store 에서 categoryStoreList 의 cascadeType.ALL을 설정 " 어느 것을 선택해야 하나??
후자를 선택한다.
이유는 간단하다. Store와 Category 중에 어느 것을 더 많이 삭제할 경우의 수가 많냐는 것이다. 가게의 삭제가 카테고리의 삭제보다 많기 때문에 후자를 선택한다.
3) 카테고리는 삭제 못하는 것인가??
이 부분에 대해서는 고민이 많다.
삭제를 못하는 것은 아니다. 하지만 비용이 많이 든다.
삭제하는 방법은 아래와 같다.
- 새로운 카테고리를 만든다.
- 새로운 카테고리의 아이디를 참조하도록 삭제하려는 카테고리의 아이디를 참조하는 CategoryStore를 모두 변경(벌크연산)한다.
- 카테고리를 삭제한다.
더 좋은 방법이 있으면 꼭 알고 싶다.
'Spring' 카테고리의 다른 글
[일지] mustache 에서 javascript 정적 리소스를 불러올 때 GET http://localhost:XXX net::ERR_ABORTED 404 (0) | 2020.09.15 |
---|---|
[일지] 쿼리가 너무 많이 전송되는데 줄일 수 없을까? (0) | 2020.09.07 |
[일지] Static 메서드로 생성하는 객체가 자동으로 save?? (0) | 2020.09.01 |
[일지] TestRestTemplate 로 테스트 하면서 궁금했던 점(feat :NoSuchBeanDefinitionException) (0) | 2020.09.01 |
[후기] 스프링 부트와 AWS로 혼자 구현하는 웹서비스 (0) | 2020.08.29 |
댓글