【问题标题】:Spring Data JPA Native Query Pagination Doesn't work on 2nd PageSpring Data JPA 本机查询分页在第二页上不起作用
【发布时间】:2018-01-27 08:25:40
【问题描述】:

我在本机查询 (SQL Server) 上使用分页,该查询适用于初始页面请求第 0 页,但当我尝试获取第 2 页的结果时因列名无效而失败。生成的查询在 SSMS 中有效,但在 Spring 中无效。

感谢任何见解。

这是错误:

Hibernate: 
    /* dynamic native SQL query */ WITH query AS (SELECT
        inner_query.*,
        ROW_NUMBER() OVER (
    ORDER BY
        CURRENT_TIMESTAMP) as __hibernate_row_nr__ 
    FROM
        ( SELECT
            TOP(?) p.ProductKey as page0_,
            p.ProductName as page1_,
            p.Sku as page2_,
            p.MaterialKey as page3_,
            p.MfgItemNumber as page4_,
            p.PackageSize as page5_,
            p.PriceUom as page6_,
            p.CasePack as page7_,
            p.ProductDescription as page8_,
            P.MediaDomain as page9_,
            p.ImagePath as page10_,
            p.ImageName as page11_,
            plp.Price as page12_,
            plp.ListPrice as page13_,
            p.SearchText  as page14_ 
        FROM
            [dbo].[BdmProductCategory] pc 
        INNER JOIN
            [dbo].BdmProduct p 
                on pc.ProductKey = p.productKey 
        INNER JOIN
            [dbo].BdmPriceListProduct plp 
                on plp.ProductKey = p.ProductKey 
        WHERE
            pc.CategoryKey = ? 
            AND pc.ProductKey > 0 
            AND pc."Delete" = 0 
            AND plp.PriceListKey = ?   -- #pageable   
        order by
            sku asc ) inner_query ) SELECT
            page0_,
            page1_,
            page2_,
            page3_,
            page4_,
            page5_,
            page6_,
            page7_,
            page8_,
            page9_,
            page10_,
            page11_,
            page12_,
            page13_,
            page14_ 
        FROM
            query 
        WHERE
            __hibernate_row_nr__ >= ? 
            AND __hibernate_row_nr__ < ?
2017-08-18 08:47:45.844 TRACE 19316 --- [nio-6193-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [BIGINT] - [4143]
2017-08-18 08:47:45.845 TRACE 19316 --- [nio-6193-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [BIGINT] - [657]
2017-08-18 08:47:45.980  WARN 19316 --- [nio-6193-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: S1093
2017-08-18 08:47:45.980 ERROR 19316 --- [nio-6193-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : The column name productKey is not valid.
2017-08-18 08:47:45.990 ERROR 19316 --- [nio-6193-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not execute query; nested exception is org.hibernate.exception.GenericJDBCException: could not execute query] with root cause com.microsoft.sqlserver.jdbc.SQLServerException: The column name productKey is not valid.

这是模型:

@Entity
@Table(name = "vw_BdmProductInfo")  // A view!
public class BdmProductInfo {

@Id
private Long productKey;
private Long    materialKey;
private String  sku;
private BigDecimal  price;
private BigDecimal  listPrice;
private String  priceUom;
private String  casePack;
private String  packageSize;
private String  mfgItemNumber;
private String  productName;
private String  productDescription;
private String  mediaDomain;
private String  ImagePath;
private String  imageName;
private String searchText;

protected BdmProductInfo() {}

....

这里是存储库:

@RestResource(path="findProductInfoByCategory")
@Query(value="SELECT p.ProductKey, p.ProductName, p.Sku, p.MaterialKey, p.MfgItemNumber, p.PackageSize, p.PriceUom, p.CasePack, p.ProductDescription, P.MediaDomain, p.ImagePath, p.ImageName, plp.Price, plp.ListPrice, p.SearchText  "
            + "FROM [dbo].[BdmProductCategory] pc "
            + "INNER JOIN [dbo].BdmProduct p on pc.ProductKey = p.productKey "
            + "INNER JOIN [dbo].BdmPriceListProduct plp on plp.ProductKey = p.ProductKey "
            + "WHERE pc.CategoryKey = :categoryKey "
            + "AND pc.ProductKey > 0 "
            + "AND pc.\"Delete\" = 0 "
            + "AND plp.PriceListKey = :priceListKey  \n-- #pageable\n ",
            countQuery="SELECT Count(*) "
            + "FROM [dbo].[BdmProductCategory] pc "
            + "INNER JOIN [dbo].BdmProduct p on pc.ProductKey = p.productKey "
            + "INNER JOIN [dbo].BdmPriceListProduct plp on plp.ProductKey = p.ProductKey "
            + "WHERE pc.categoryKey = :categoryKey "
            + "AND pc.ProductKey > 0 "
            + "AND pc.\"Delete\" = 0 "
            + "AND plp.PriceListKey = :priceListKey ",nativeQuery=true)
    Page<BdmProductInfo> findProductInfoByCategory(@Param("categoryKey") Long categoryKey, @Param("priceListKey") Long priceListKey, Pageable pageable );

【问题讨论】:

  • productKey 列好像不存在?!您能否在此处检查日志:无法执行查询] 根本原因 com.microsoft.sqlserver.jdbc.SQLServerException:列名 productKey 无效。你确定第一次调用成功了吗?!
  • 是的,第一次调用成功......但查询与第二次请求不同。第一个查询Hibernate使用了Top函数,第二个使用了WITH QUERY、row_nbr等......如下图..
  • WITH 查询 AS (SELECT inner_query.*, ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as hibernate_row_nr FROM (SELECT TOP(?) p.ProductKey as page0_, p. ProductName 作为 page1_,p.Sku 作为 page2_,p.MaterialKey 作为 page3_,p.MfgItemNumber 作为 page4_,p.PackageSize 作为 page5_,p.PriceUom 作为 page6_,p.CasePack 作为 page7_,p.ProductDescription 作为 page8_,P.MediaDomain 作为page9_, p.ImagePath as page10_,
  • p.ImageName as page11_, plp.Price as page12_, plp.ListPrice as page13_, p.SearchText as page14_ FROM [dbo].[BdmProductCategory] ​​pc INNER JOIN [dbo].BdmProduct p on pc .ProductKey = p.productKey INNER JOIN [dbo].BdmPriceListProduct plp on plp.ProductKey = p.ProductKey WHERE pc.CategoryKey = ? AND pc.ProductKey > 0 AND pc."Delete" = 0 AND plp.PriceListKey = ? -- #pageable
  • 这就是问题所在......在为查询列创建别名后,Hibernate 使用别名而不是尝试生成自己的别名......导致问题。因此,在查询中,为每一列选择 p.productKey 作为 productKey 等的别名,这有助于获取后续页面 ... FWIW 为遇到此问题的其他人提供...

标签: sql spring pagination spring-data spring-data-jpa


【解决方案1】:

在为查询列设置别名后,Hibernate 使用 别名而不是尝试生成自己的...导致 问题。因此,在查询中,为选定的每一列添加别名p.productKey as productKey,等等......这有助于获取后续页面...... FWIW 对于遇到此问题的其他人...

致谢:@Don

【讨论】:

  • 我也有同样的问题,但是你的unswer 对我不起作用。你能帮帮我吗?
猜你喜欢
  • 2018-11-25
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
  • 2016-08-26
相关资源
最近更新 更多