강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

비트리올님의 프로필 이미지
비트리올

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

도메인 모델과 테이블 설계

OrderItem이 item의 id(pk)를 fk를 가지는 방식으로 매핑할때 문제점

작성

·

373

1

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
Order, Item이 있고. Order와 Item사이의 다대다 관계를 풀기 위해서 OrderItem이 존재합니다.

이때, OrderItem은 Order의 pk와 Item의 pk를 갖습니다.

 

위와 같은 상황에서. OrderItem에 들어가있는 Item을 삭제하려고 하면. 삭제를 할 수 없다는 문제점이 발생할 것 같습니다.

Item을 삭제하면. 과거주문내역(즉, OrderItem)을 조회했을때 Item이 다 null로 나오겠죠. 애초에 참조무결성이 깨지기 때문에 삭제가 안될지도 모르겠습니다. 또는, Item을 삭제할때 연관되어있는 모든 OrderItem역시 같이 지워야 한다거나요.

게다가, 이는 비즈니스 정책에 따라 다르겠지만. item의 이름을 변경할 경우. 과거 모든 주문내역에서 item의 이름이 변경된다는 단점도 있습니다. 클라이언트가 이를 원할 수 도 있겠으나. 개인적으로는 이미 판매한 주문내역의 item 이름이 변경되는것은 어색하다고 생각합니다.

 

저의 질문은. 실무에서, 현장에서는 Order와 Item사이의 연관관계를 어떻게 처리하고 있는지 궁금합니다. 어떻게 처리하는지에 따라 delete와 update의 작동 방식이 달라진다고 생각하기 때문입니다. 저 스스로 생각해본 방식으로는 두가지가 있습니다.

첫번째는, OrderItem에서 Item Long id(pk)가 아닌 Item의 String name을 들고 있는 것 입니다. 이 경우. Item이 삭제되어도, name으로 itemRepository.findByName(name)를 이용해 데이터를 조회합니다. 하지만 name으로 entity를 식별해야하므로. name이 유니크해야하며. name이 같으면 동일한 entity로 보기때문에, 한번 삭제했다가 같은이름으로 다시 item을 만들경우 이 둘을 동일하게 취급한다는 문제점이 있을것 같습니다. update관점에서는, item Long id(pk)가 아닌 item의 name을 들고있기 때문에. item을 업데이트 하더라도, 과거 주문내역의 item들의 이름이 바뀌지 않을 것입니다.

두번째는, 삭제를 하지 않는 것입니다. 대신 pseudo삭제를 구현합니다. entity에 Boolean enable;과 같은 필드를 만들고. 이 필드값의 T/F 여부에 따라 pseudo삭제되었는지 아닌지 판별합니다. item의 name이 같은 List<Item>에서 최대 하나의 item만 enable true상태를 갖도록 합니다. 이렇게 했을경우 각 OrderItem(주문내역)은 각각 다른 item과 pk로 매핑되어 있기 때문에, 가장 최신에 사용하고 있는(enable=true)인 item을 업데이트하더라도 과거 주문내역에 영향을 끼치지 않습니다. 또한 실제로 db에서 데이터를 삭제하는 것이 아니기 때문에. 과거 내역을 조회할때 item = null인 상황도 발생하지 않을 것입니다. 단, db에 delete를 날리지 않으니 데이터가 계속 쌓인다는 단점이 있을것 같습니다.

 

위의 두가지 방법은 그저 재가 생각해본 방법에 불과하고. 올바른 방법이 있다면 알려주세요. 부탁드립니다 선생님.

질문이 장황하고 굉장히 길었습니다. 읽어주셔서 너무나 감사합니다.

답변 1

1

안녕하세요. 비트리올님, 공식 서포터즈 David입니다.

동일한 도메인은 아니지만 특정 시점에 발생한 이벤트에 대해 스냅샷을 남겨야 하는 요구사항이 있었습니다.

만약 특정 시점에 발생한 주문내역을 다른 테이블의 레코드 변경과 무관하게 관리해야 한다면 특정 시점에 발생한 주문내역을 보관하는 테이블을 별도로 만들 것 같습니다.

감사합니다.

비트리올님의 프로필 이미지
비트리올

작성한 질문수

질문하기