주문 도메인 개발 - cascade (복습)

박경희·2025년 1월 20일
0

강의 복습 및 정리

목록 보기
32/38
post-thumbnail

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

/**
 * 주문
 */
@Transactional
public Long order(Long memberId, Long itemId, int count) {

    //엔티티 조회
    Member member = memberRepository.findOne(memberId);
    Item item = itemRepository.findOen(itemId);

    //배송정보 생성
    Delivery delivery = new Delivery();
    delivery.setAddress(member.getAddress());
    
     //주문상품 생성
    OrderItem orderItem = OrderItem.createOrderItem(item, item.getPrice(), count);


    //주문 생성
    Order order = Order.createOrder(member, delivery, orderItem);

    //주문 저장
    orderRepository.save(order);

    return order.getId();
}
  • 원래라면 delivery도 repository를 따로 만들고 orderItem도 jpa한테 넣어준 다음에 order에 값을 세팅해줘야 한다.
    그런데 여기선 order만 save했다. why~?
@OneToMany(mappedBy = "order", cascade = ALL)
private List<OrderItem> orderItems = new ArrayList<>();
  • Cascade= All을 했기 때문이다.
    =>order를 persist 하면 orderItem에 들어온 것들도 모두 persist 되도록.
@OneToOne(fetch = LAZY, cascade = ALL)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
  • delivery도 cascade를 걸어서 order가 persist 될 때 함께 persist 된다.
    따라서 orderRepository.save(order);하나만으로 delivery와 orderItem까지 저장되는 것이다.

cascade의 범위에 대해서는 고민이 필요하다.

  • 어디까지 cascade를 해줘야 하는가?
  • 어떤개념에서 쓰는게 좋은가?

=> 여기서는 order가 delivery를 관리하고 order가 orderItem을 관라한다. 이런 그림 정도에서만 써야한다.

  • delivery나 orderItem은 order에서만 참조하여 사용한다. 딱 요정도에서 사용하는게 좋다.(라이프 사이클에서 동일하게 관리를 할 때 의미가 있다.)

예를 들어 delivery가 매우 중요해서 여기 저기서 참조하여 쓴다면?? -> cascade를 쓰면 안된다!

  • 다른데서 참조하여 쓰는 곳이 많다면 별도의 repository를 생성하여 각각 persist 해줘야 한다.

개념이 확실하지 않다면 cascade는 사용하지 않는게 좋다.

  • 코드 리팩토링을 하면서 확실하게 '이런 데에서는 써도 괜찮겠다' 싶은면 그 때 넣어주면서 알아가는게 좋다.

누군가가 new로 orderItem을 만들어 사용할 수도 있다
-> 이렇게 여기 저기서 쓰는 방법이 달라지면 안되기 때문에 이를 막아주어야 한다.

protected OrderItem() {
}
  • new 해서 생성하는걸 막는것. jpa에서 protected를 쓰면 쓰지 말라는거다.
@NoArgsConstructor(access = AccessLevel.PROTECTED)  
  • 이렇게 롬복으로 할 수 있다.

-> 누군가 new 해서 만들면 빨간불이 뜨고 들어가보면 protected를 보면 '다른 방법으로 생성해야 하는구나' 하고 알 수 있도록.

0개의 댓글