Order
엔티티가OrderItem
엔티티의 컬렉션을 필드로 가지고 있다고 가정한다.
public List<Order> findAllWithItem() {
return em.createQuery(
"select distinct o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d" +
" join fetch o.orderItems oi" +
" join fetch oi.item i", Order.class)
.getResultList();
}
fetch join
하여 가져온다.distinct
키워드를 통해, Order
엔티티를 기준으로 중복 제거 후 반환도 가능하다.그러나, 치명적인 단점이 있다.
fetch join
을 통한 컬렉션 조회는, 페이징 처리가 큰 리스크가 된다.
N:1
관계는 모두 fetch join
한다. row 수에 영향을 주지 않으므로 페이징 쿼리에 아무 영향이 없다.단, batch를 이용해 지연로딩한다.
내부적으로 IN
쿼리를 이용하므로 성능 최적화에 좋다.
예를 들어, 만개 row의 내부 컬렉션을 모두 조회한다고 가정하면,
batch_size
가 1000이라면 단 10번만 조회해도 된다.
반대로,batch_size
가 1이라면 만번의 쿼리 요청이 일어나게 된다.