강의

멘토링

커뮤니티

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

educrinity5님의 프로필 이미지
educrinity5

작성한 질문수

제미니의 개발실무 - 커머스 백엔드 기본편

엔티티 연관관계 사용

해결된 질문

작성

·

38

·

수정됨

1

안녕하세요, 강의 너무 잘보고있습니다!

코드를 살펴보니 궁금한 부분이 있는데 현재 작성된 코드에서는 엔티티 간 연관관계를 맺지 않고 풀어내고계시더라고요!
재미니님은 실무에서도 연관관계를 사용하지 않으시는 건지 아니면 고민 포인트(?)를 던져주신건지 궁금합니다!

예를들어 Order와 OrderItem 관련해서, OrderService의 서비스 레이어인 create 메서드에서 OrderItemRepository를 사용해 saveAll을 호출하는 방식을 사용하시더라고요!

저는 Order가 없으면 OrderItem은 존재하지 않아야한다고 생각해서, OrderItem의 생성을 서비스 레이어가 아닌 Order 엔티티안에서 생성하도록 강제하는 건 어떨까 생각했습니다.

방법으로는

  1. OrderItem.create() 같은 생성 메서드를 protected로 막는다.

  2. OrderItemRepository를 아예 생성하지 않는다.

  3. 더티 체킹을 이용하여 Order 필드에 있는 List<OrderItem> 컬렉션에 요소 추가로 OrderItem을 save한다.

  4. 팀 컨벤션을 정한다.

정도가 있을 것 같은데... 그렇다면 재미니님은 실무에서도 연관관계를 맺지 않는 방식을 선호하시는 건가요?

사실 서비스 레이어에서 직접 호출을 통한 저장이라고 해도 문제는 없겠지만 사용하시는 방식이 궁금합니다!

 

그리고 추가적으로 주문 시 상품 재고를 차감시키는 메서드를 OrderHandler(OrderManager) 에 private으로 위치시키는 것과 ProductHandler(ProductManager)에 위치시키고 주입받아 사용하는 것중 어떤게 더 나은 방식일까요?

private void decreaseProductStock(List<NewOrderItem> newOrderItems, Map<Long, Product> productMap) {
        for (NewOrderItem newOrderItem : newOrderItems) {
            Product product = productMap.get(newOrderItem.productId());
            if (product.isStockLessThan(newOrderItem.quantity())) throw new ApiException(PRODUCT_QUANTITY_OVER);
            product.decreaseStock(newOrderItem.quantity());
        }
    }

고민이 되는 부분은 예를들어 위와 같은 메서드를 OrderHandler에 두자니 조금 헤비해지는 것 같고, ProductHandler에 두자니 신규 주문 시에만 사용될 것같은데.. ProductHandler에 두는게 맞는지 고민입니다..! 의견이나 힌트 주시면 좀 더 고민해보도록 하겠습니다!

답변 1

1

제미니님의 프로필 이미지
제미니
지식공유자

안녕하세요 질문 감사드립니다!

우선 핵심만 말하면 저는 실무에서도 생명주기 가 같지 않으면 연관관계를 걸지 않습니다
또한 양방향 관계는 걸지않고, 가급적 OneToMany는 정말 필요한 상황이 아니면 사용하지 않습니다

지금 예제로 보면 Order -> OrderItem 은 관계를 맺지 않고 OrderItem -> Order 정도는 걸 수 있다고 보긴합니다!

이는 결국 "Order 가 OrderItem 을 필수로 알아야하는가?" 가 핵심입니다 단순히 생성 관점으로만 보지 않고 조회 패턴 (Order 조회 시 OrderItem 을 항상 가져와야하는가? Lazy 로 걸면 되지만, 그럼에도 관계가 있어야하는 이유가 무엇일까? 등의 고민)

그래서 저는 가급적 관계 보다는 조합을 선호하고 추후에 필요 시 관계를 지정하는 편입니다
(사실 관계를 걸었다가 푸는 것 보다, 안 걸고 키로 조합하다가 거는게 수정이 쉽고, 사이드이펙트가 적은편입니다)

이건 일반적으로 제가 사용하는 전략이라 적어주신 것 처럼 팀 컨벤션을 정하는게 좋습니다, 다만 단순히 생성 관점에서만으로 접근하는 것은 좀 더 생각해봐야하는 부분 같습니다 OrderItemRepository는 분명히 다른 구현 때문에라도 어짜피 생길 것 이기 떄문입니다
(꾸역꾸역 안 만들겠다면 정산 로직에서 OrderItem 단위 정산을 할때 Order 를 조회해서 분류하거나 OrderRepository에 조금 과한 쿼리가 다 들어가야겠죠)


추가적으로 주신 질문은 잘 생각해보면 상품과 재고를 같은 관점으로 볼 것인가를 고민해보면 좋을 것 같습니다

정확히 보면 재고상품과 직접 연관이 있어야하는가?에 대한 고민을 해볼 수 있을 것 같습니다, 타협할 수 있는 전략으로는 ProductStockXXX 같은 친구를 만들어서 해당 역할을 맡길 수 있을 것 같습니다.

추가로 더 고민해보실 거리를 드리면 정확히하면 재고는 주문 보단 "결제/취소"하고 상당히 가깝습니다
가령 주문 생성시 재고를 차감한다면 복원은 언제해야할까요?, 그리고 주문 생성하고 사이트를 끄거나 하는 사람의 재고는 어떻게 처리해야할까요?

등등 관점으로 한번 더 생각해보시면 좋을 것 같습니다!


연관관계 관련 주제에 대한 제 유튜브 영상도 링크드리오니 궁금하시면 한번 보시길 바랍니다!
https://www.youtube.com/watch?v=vgNHW_nb2mg
https://www.youtube.com/watch?v=j9bcvidVQgg
https://www.youtube.com/watch?v=VGp1g9irQRI


모쪼록 답이 되었길 바랍니다! 감사합니다!
완강까지 잘 부탁드리고 수강평도 기대하겠습니다! 추가 질문이 있다면 편하게 주세요!

educrinity5님의 프로필 이미지
educrinity5

작성한 질문수

질문하기