시도

아래와 같이 DB에서 페이징으로 정보를 가져와한다 .하지만 N+1 문제가 발생해 @Query 로 쿼리를 직접 적어 fetch join을 시도했다.

userRepository.findAll(pageable)

 

 

문제발생

Pageable를 사용한 조회시 n+1문제가 발생해 @Query("SELECT S FROM ADMIN S LEFT JOIN FETCH....") 를 사용하여 문제를 해결하려고 했다. 하지만 아래와 같은 에러가 발생.

Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=null,role=com.ro.lib.visit.entity.VisitEntity.comments,tableName=visitdb.visit_comment,tableAlias=comments1_,origin=visitdb.visit visitentit0_,columns={visitentit0_.visit_id ,className=com.ro.lib.visit.entity.VisitCommentEntity}}] [select count(v) FROM com.ro.lib.visit.entity.VisitEntity v LEFT JOIN FETCH v.comments WHERE v.venue.id = :venueId and (v.actualArrival > :date or v.arrival > :date)]
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1374)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:309)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

 

해결방안

countQuery를 이용해 쿼리 전체 갯수를 세준다. 그러면 페이징과 join fetch를 사용할 수 있다.

@Query(value = "select o from Order o join fetch o.member m join fetch o.delivery d",
	countQuery = "select count(o) from Order o")
public Page<Order> findAllWithMemberDelivery(Pageable pageable);

 

복사했습니다!