【问题标题】:Spring Data paginationSpring数据分页
【发布时间】:2020-03-04 10:39:05
【问题描述】:

只是面对 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&lt;Object[]&gt;而不是Page&lt;Product&gt;。如果我在返回类型中将Page 更改为List,一切都会好起来的。为什么它会这样工作?是否可以改变这种行为?

我使用select p, c 通过一次查询将产品和类别中的所有数据填充到结果产品中。没有cHibernate 做一些额外的查询来获取类别。

【问题讨论】:

  • 如果您使用现有的 Spring Data repo 方法,您能否检查是否也会发生这种情况,例如Page&lt;Product&gt; findAll();?
  • 也许还发布您的相关实体类...可以帮助
  • 可能是重复的...请看一下:stackoverflow.com/questions/6877857/…
  • 据我所知,要使用延迟加载字段,它必须具有optional=false 参数。但是Category 是可选的。您可以尝试添加 EmptyCategory 值而不是 null。然后尝试使用join fetch 而不是left join fetch

标签: java hibernate pagination spring-data-jpa


【解决方案1】:

您的存储库接口是否扩展 JpaRepositoryPagingAndSortingRepository,例如像这样(其中Long 是您的实体@Id 字段的类型:

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

    // your custom repo methods...
}

【讨论】:

    【解决方案2】:

    试试这个

    @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);
    

    【讨论】:

    • 此查询通过单独的选择获取每个类别。我正在寻找一种方法如何通过一个带有连接的查询来强制 Hibernate 做到这一点。
    【解决方案3】:

    为了计算正确的页面信息,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)",
    

    ) 页面 filterProducts(@Param("categoryId") 长 categoryId, @Param("priceFrom") BigDecimal priceFrom, @Param("priceTo") BigDecimal priceTo, 可分页的);

    【讨论】:

      猜你喜欢
      • 2013-12-20
      • 2020-03-11
      • 1970-01-01
      • 2019-08-31
      • 2017-12-20
      • 2017-06-15
      • 2015-07-24
      • 2016-05-30
      • 2017-12-20
      相关资源
      最近更新 更多