코드 그라데이션

shop 구현 (5) 고아객체 제거, 즉시 로딩과 지연 로딩 본문

Spring/SpringShop

shop 구현 (5) 고아객체 제거, 즉시 로딩과 지연 로딩

완벽한 장면 2023. 7. 12. 13:49

지연로딩을 기본값으로 설정하라는 대전제

 

어노테이션

@OneToOne, @ManyToOne 처럼 뒤가 One으로 끝나면 default가 EAGER (즉시)

@OneToMany, @ManyToMany 처럼 뒤가 Many로 끝나면 default가 LAZY (지연)

 

 

 orphanRemoval  고아 객체 제거

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) 

private List<OrderItem> orderItems = new ArrayList<>();

 

Order가 여러 개의 OrderItem 을 들고 있는데, 지금 이 관계에서는 OrderItem이 자식에 가깝다.

그런데 만약 Order가 삭제가 되었다. 그럼 OrderItem은 고아가 된 것. 

그럼 Orderitem까지 삭제시켜버리는 건 Cascade옵션

 

테스트를 보면 조금 더 명확하게 구분할 수 있을 듯 한데,

public Order createOrder() {
    Order order = new Order();
    for (int i=0; i<3; i++) {
      Item item = createItem();
      itemRepository.save(item);
      OrderItem orderItem = new OrderItem();
      orderItem.setItem(item);
      orderItem.setCount(10);
      orderItem.setOrderPrice(10000);
      orderItem.setOrder(order);
      order.getOrderItems().add(orderItem);
    }
    Member member = new Member();
    memberRepository.save(member);
    order.setMember(member);
    orderRepository.save(order);
    return order;
  }

  @Test
  @DisplayName("고아객체 제거 테스트")
  public void orphanRemovalTest() {
    Order order = this.createOrder();
    order.getOrderItems().remove(0);
    em.flush();
  }

  @Test
  @DisplayName("고아객체 제거 테스트")
  public void orphanRemovalTest() {
    Order order = this.createOrder();
    order.getOrderItems().remove(0); // 부모 order에게서 첫 번째 orderItem을 제거한 것.
    em.flush();
  } 이것만 봤을 때는

 // 부모 order에게서 첫 번째 orderItem을 제거한 것. -> 리스트에서 빠져나와서 붕 뜬 거니까 우리가 delete하라는 명령을 안 날렸지만 orphanRemoval가 붙어있는 것 때문에 객체 세상에서 얘를 떼어낸 것 만으로도 DB에서 얘가 제거가 될 것.

 


지연로딩의 사용시점은 '사용할 때'

만약 트랜잭션 내내 얘를 안 썼으면 사용 안하고 넘어감

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)

private List<OrderItem> orderItems = new ArrayList<>();

여기서 보면

내가 Order를 조회하면 orderItem은 레이지 로딩이기 때문에 아직 안 채워진 상태다

그런데 내가 오더만 조회하고 오더아이템에서는 아무것도 안 할 가능성도 존재.  

그럼 이 트랜잭션에서는 애 쿼리를 안 날리고 가져오지 않는다.

이게 지연로딩의 힘(메모리 낭비 방지) 

 

728x90

'Spring > SpringShop' 카테고리의 다른 글

shop 구현 (7) 상품 등록  (0) 2023.07.13
shop 구현 (6) Auditing  (0) 2023.07.12
shop 구현 (4) 연관관계 매핑  (0) 2023.07.11
shop 구현 (3) Entity, Dto, Service 계층 + QueryDsl  (0) 2023.07.09
shop 구현 (2) Controller, Model  (0) 2023.07.08
Comments