엔티티 조회 최적화

HUSII·2023년 7월 10일
0

JPA

목록 보기
3/7

ToOne(OneToOne, ManyToOne)의 연관관계가 있는 엔티티를 같이 조회한다고 할때 최적화 방법을 알아보겠다.


엔티티들의 연관관계 설명

ORDER, MEMBER, DELIVERY 총 3개의 엔티티가 있다.
ORDER와 MEMBER는 ManyToOne 관계
ORDER와 DELIVERY는 OneToOne 관계


ORDER 엔티티의 모든 필드를 API로 리턴한다고 했을때
List<Order> 그대로 리턴하면 오류가 난다.

order 엔티티에 있는 member와 delivery 엔티티의 필드에 order 엔티티가 있기 때문에 무한루프가 된다.
@JsonIgnore을 붙히면 무한루프를 막을 수 있지만, 계층 분리를 위하여 API용 Dto를 따로 구현해놓는게 좋다.


order 엔티티를 Dto로 변환한다고 했을때 1+n 문제가 있다.
맨처음 List<Order>를 조회하는 쿼리 1개를 보내고, 이 다음 order 엔티티에 있는 member, delivery 엔티티는 지연 로딩이기 때문에, 각각의 order 엔티티당 1번씩 총 n개의 추가 쿼리를 보내게 된다.
따라서 총 1+n+n개의 쿼리를 보내게 된다.

물론 같은 객체를 참조하고 있다면, 영속성 컨텍스트의 1차캐시에 의해 n개보단 적게 보낼 수 있다.


이때 fetch join을 이용하면 쿼리1번만에 모든 엔티티를 조회할 수 있다.

select o from Order o 
	join fetch o.member m 
    join fetch o.delivery d

JPA에서 바로 Dto를 통해 조회할수도 있지만,
리포지토리 재사용성이 떨어지고, API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점이 있다

예시

em.createQuery(
"select new jpabook.jpashop.repository.order.simplequery.OrderSimpleQueryDto
(o.id, m.name, o.orderDate, o.status, d.address)" +
" from Order o" +
" join o.member m" +
" join o.delivery d", OrderSimpleQueryDto.class)
.getResultList();
profile
공부하다가 생긴 궁금한 것들을 정리하는 공간

0개의 댓글