Spring Data pagination - PullRequest
       10

Spring Data pagination

0 голосов
/ 07 ноября 2019

Просто столкнитесь со странным поведением Spring Data JPA 2.2.0.

Product и Category - это две очень простые сущности с отношениями один-ко-многим. Обратите внимание, что в моем случае некоторые продукты могут не иметь никакой категории.

Я делаю этот запрос

@Query("select p, c" +
        "from Product p " +
        "left join fetch Category c on p.category.id = c.id " +
        "where (:categoryId = -1L or c.id = :categoryId) and " +
        "(:priceFrom is null or p.price >= :priceFrom) and " +
        "(:priceTo is null or p.price <= :priceTo)")
Page<Product> filterProducts(@Param("categoryId") Long categoryId,
                             @Param("priceFrom") BigDecimal priceFrom,
                             @Param("priceTo") BigDecimal priceTo,
                             Pageable pageable);

Но вызов метода возвращает Page<Object[]> вместо Page<Product>. Если я изменю Page на List в типе возврата, все будет хорошо. Почему так работает? Можно ли изменить это поведение?

Я использую select p, c, чтобы заполнить итоговые продукты всеми данными из продукта и категории одним запросом. Без c Hibernate не выполняет некоторые дополнительные запросы для получения категорий.

Ответы [ 3 ]

0 голосов
/ 08 ноября 2019

Попробуйте это

@Query("from Product p left join fetch p.category c " +
       "where (:categoryId = -1L or c.id = :categoryId) and " +
       "(:priceFrom is null or p.price >= :priceFrom) and " +
       "(:priceTo is null or p.price <= :priceTo)")
Page<Product> filterProducts(@Param("categoryId") Long categoryId,
                                     @Param("priceFrom") BigDecimal priceFrom,
                                     @Param("priceTo") BigDecimal priceTo,
                                     Pageable pageable);
0 голосов
/ 09 ноября 2019

Чтобы рассчитать правильную информацию о странице, Spring JPA также необходимо максимальное количество строк. (для расчета номеров страниц). Чтобы получить это, вам нужно предоставить countQuery в дополнение к исходному определению запроса:

@Query(value = "select p, c" +
        "from Product p " +
        "left join fetch Category c on p.category.id = c.id " +
        "where (:categoryId = -1L or c.id = :categoryId) and " +
        "(:priceFrom is null or p.price >= :priceFrom) and " +
        "(:priceTo is null or p.price <= :priceTo)",
       countQuery = "select count(p.id)" +
        "from Product p " +
        "left join fetch Category c on p.category.id = c.id " +
        "where (:categoryId = -1L or c.id = :categoryId) and " +
        "(:priceFrom is null or p.price >= :priceFrom) and " +
        "(:priceTo is null or p.price <= :priceTo)",

) Page filterProducts (@Param ("categoryId") Длинный categoryId, @Param ("priceFrom") BigDecimal priceFrom, @Param ("priceTo") BigDecimal priceTo, Pageable Pageable);

0 голосов
/ 07 ноября 2019

расширяет ли ваш интерфейс хранилища JpaRepository или PagingAndSortingRepository, например, вот так (где Long - тип вашей сущности @Id поле:

@Repository
interface ProductRepository extends JpaRepository<Product, Long> {

    // your custom repo methods...
}
...