컬렉션이 있는 경우의 DTO 직접 조회

OrderDTO를 안 사용하고 따로 만든 이유는 관심사가 다르기 때문이다.

@Repository
@RequiredArgsConstructor
public class OrderQueryRepository {

	private final EntityManager em;

	public List<OrderQueryDTO> findOrderQueryDTOs() {
		return em.createQuery("select new jpabook.jpashop.repository.order.query.OrderQueryDTO(o.id, m.name, o.orderDate, o.status, o.delivery.address) from Order o" +
					" join o.member m" +
					" join o.delivery d", OrderQueryDTO.class)
				.getResultList();
	}
}
@Repository
@RequiredArgsConstructor
public class OrderQueryRepository {

	private final EntityManager em;

	public List<OrderQueryDTO> findOrderQueryDTOs() {
		List<OrderQueryDTO> result = findOrders();
		result.forEach(o -> {
			List<OrderItemQueryDTO> orderItems = findOrderItems(o.getOrderId());
			o.setOrderItems(orderItems);
		});

		return result;
	}

	private List<OrderItemQueryDTO> findOrderItems(Long orderId) {
		return em.createQuery("select new jpabook.jpashop.repository.order.query.OrderItemQueryDTO(oi.order.id, oi.item.name, oi.orderPrice, oi.count) from OrderItem oi" +
					" join oi.item i" +
					" where oi.order.id = :orderId", OrderItemQueryDTO.class)
				.setParameter("orderId", orderId)
				.getResultList();
	}

	private List<OrderQueryDTO> findOrders() {
		return em.createQuery("select new jpabook.jpashop.repository.order.query.OrderQueryDTO(o.id, m.name, o.orderDate, o.status, o.delivery.address) from Order o" +
					" join o.member m" +
					" join o.delivery d", OrderQueryDTO.class)
				.getResultList();
	}
}

정리