@Autowired
OrderItemRepository orderItemRepository;
@Test
@DisplayName("지연 로딩 테스트")
public void lazyLoadingTest(){
Order order = this.createOrder() //기존에 만들었던 주문 생성 메소드를 이용하여 주문 데이터 저장
Long orderItemId = order.getOrderItems().get(0).getId();
em.flush();
em.clear();
OrderItem orderItem = orderItemRepository.findById(orderItemId)
.orElseThrow(EntityNotFoundException::new);
System.out.println("order cass : " +
orderItem.getOrder().getClass());
}
}
order 엔티티 하나를 조회했을 뿐인데
order_item 테이블, item, orders, member 테이블 조인해서 한꺼번에 가지고 옴
* 일대일, 다대일로 매핑할 경우 기본 전략인 즉시 로딩을 통해 엔티티를 함께 가지고 옴
이처럼 매핑되어 있는 엔티티가 많을수록 쿼리가 어떻게 실행될지 예측할 수 없고 성능 문제도 있을 수 있기 때문에 즉시 로딩은 실무에서 잘 사용하지 않음 -> 지연 로딩 방식 사용하기 (FetchType.LAZY)
지연 로딩 방식
@ManyToOne
@JoinColumn(name = "item_id")
private Item item; //하나의 상품은 여러 주문 상품으로 들어갈 수 있으므로 주문 상품 기준 다대일 단방향 매핑
@ManyToOne
@JoinColumn(name = "order_id")
private Order order; // 한번의 주문에 여러 개의 상품을 주문할 수 있으므로 주문 상품 엔티티와 주문 엔티티를 다대일 단방향 매핑을 먼저 설정
OrderItem의 두 코드를 지연 로딩 방식으로 바꾸기
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id")
private Item item; //하나의 상품은 여러 주문 상품으로 들어갈 수 있으므로 주문 상품 기준 다대일 단방향 매핑
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id")
private Order order; // 한번의 주문에 여러 개의 상품을 주문할 수 있으므로 주문 상품 엔티티와 주문 엔티티를 다대일 단방향 매핑을 먼저 설정
지연 로딩 설정 후 OrderItem에 매핑된 Order 클래스 출력 결과
HibernteProxy 출력: 지연 로딩으로 설정하면 실제 엔티티 대신에 프록시 객체를 넣어둠
프록시 객체는 실제로 사용되기 전까지 데이터 로딩을 하지 않고, 실제 사용 시점에 조회 쿼리문이 실행됨