Spring-Data FETCH JOIN with Paging не работает
Я пытаюсь использовать HQL, получая мою сущность вместе с суб-сущностями, используя JOIN FETCH, это работает нормально, если я хочу все результаты, но это не так, если я хочу страницу
Моя сущность
@Entity @Data public class VisitEntity { @Id @Audited private long id; . . . @OneToMany(cascade = CascadeType.ALL,) private List comments; }
и потому, что у меня есть миллионы посещений, мне нужно использовать «Pageable», и я хочу «Получить комментарии» в одном запросе базы данных, например:
- ImprovedNamingStrategy больше не работает в Hibernate 5
- Весенние данные и исходный запрос с разбивкой на страницы
- Как добавить пользовательский метод в Spring Data JPA
- Объединение двух элементов таблицы в Spring Data JPA
- Spring Data JPA: пакетная вставка для вложенных объектов
@Query("SELECT v FROM VisitEntity v LEFT JOIN FETCH v.comments WHERE v.venue.id = :venueId and ..." ) public Page getVenueVisits(@Param("venueId") long venueId,..., Pageable pageable);
Этот вызов HQL вызывает следующее исключение:
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)
и как только я удаляю пейджинг, все работает нормально
@Query("SELECT v FROM VisitEntity v LEFT JOIN FETCH v.comments WHERE v.venue.id = :venueId and ..." ) public List getVenueVisits(@Param("venueId") long venueId,...);
Очевидно, проблема связана с запросом count от Spring-Data, но как мы можем его исправить?
- setMaxResults для annotations Spring-Data-JPA?
- Spring JPA выбирает определенные столбцы
- Весовые данные JPA-запрос с параметрическими свойствами
- Как работает FetchMode в Spring Data JPA
- POSTing ассоциация суб-ресурсов @OneToMany в Spring Data REST
- Отключите всю конфигурацию, связанную с базой данных, в Spring Boot
- Spring Boot & JPA: реализация поисковых запросов с дополнительными критериями дальности
- Отключить язык приложений гипертекста (HAL) в JSON?
Самый простой способ – использовать атрибут @Query
annotations @Query
для предоставления пользовательского запроса для использования.
@Query(value = "SELECT v FROM VisitEntity v LEFT JOIN FETCH v.comments …", countQuery = "select count(v) from VisitEntity v where …") List getVenueVisits(@Param("venueId") long venueId, …);
Вы должны указать параметр countQuery
для @Query
и теперь вы можете использовать Page
или List
как возвращаемое значение.
@Query(value = "SELECT v FROM VisitEntity v LEFT JOIN FETCH v.comments WHERE v.venue.id = :venueId and ...", countQuery = "SELECT count(v) FROM VisitEntity v LEFT JOIN v.comments WHERE v.venue.id = :venueId and ..." ) public Page getVenueVisits(@Param("venueId") long venueId,..., Pageable pageable);
Альтернативно, в новейших версиях Spring (поддерживая спецификацию JPA 2.1) вы можете использовать граф сущности следующим образом:
@EntityGraph(attributePaths = "roles") @Query("FROM User user") Page findAllWithRoles(Pageable pageable);
Разумеется, именованные диаграммы сущностей также работают.