【问题标题】:JPA / Hibernate pagination in MS SQL Server 2008 eror mapping to objectMS SQL Server 2008 中的 JPA / Hibernate 分页错误映射到对象
【发布时间】:2014-05-31 07:16:12
【问题描述】:

鉴于我的代码如下:

Query q = em.createNativeQuery(sql.toString(), SearchDTO.class);
for (String k : parameters.keySet()) {
    q.setParameter(k, parameters.get(k));           
}
q.setFirstResult((criteria.getPage()-1) * criteria.getLimit());
q.setMaxResults(criteria.getLimit());       

return q.getResultList();

其中page>1,生成的sql不正确:

WITH query AS (SELECT inner_query.*, ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as hibernate_row_nr FROM (select TOP(?) cc.company_id as page0_, cc.long_name 作为 page1_,cc.reuters_org_id 作为 page2_,ccdom.country_name 作为 country_of_domicile,ccinc.country_name 作为 country_of_incorporation,ccr.region_name 作为地区,ci.industry_name 作为行业来自zz_prp_common_company cc 左加入 zz_prp_common_country ccdom 上 cc.country_of_domicile = ccdom.country_id 左加入 zz_prp_common_region ccr 上 ccr.region_id = ccdom.region_id 左加入 zz_prp_common_country ccinc 上 cc.country_of_domicile = ccinc.country_id 左加入 zzindustry.industry.common_industry where 1=1 order by cc.long_name ) inner_query ) SELECT page0_, page1_, page2_, country_of_domicile, country_of_incorporation, region, industry FROM query WHERE hibernate_row_nr >= ? AND hibernate_row_nr

我不明白为什么它将我的列的别名替换为 page0_、page1_ 和 page2_。由于这个 where page0_ 替换了 company_id 列别名,我收到了这个错误:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The column name company_id is not valid.

我正在使用 MS SQL Server 2008 R2,并且我已将我的休眠方言设置为使用 org.hibernate.dialect.SQLServer2008Dialect。

【问题讨论】:

    标签: java sql-server-2008 hibernate orm pagination


    【解决方案1】:

    我已经找到了这个问题的答案。我使用的 sql 本机查询在前 3 列(company_id、long_name 和 reuters_org_id)上没有任何别名。当我调试 SQLServer2008Dialect 时,它导致方法 getProcessedSql():

    public String getProcessedSql() {
            StringBuilder sb = new StringBuilder( sql );
            if ( sb.charAt( sb.length() - 1 ) == ';' ) {
                sb.setLength( sb.length() - 1 );
            }
    
            if ( LimitHelper.hasFirstRow( selection ) ) {
                final String selectClause = fillAliasInSelectClause( sb );
    
                int orderByIndex = shallowIndexOfWord( sb, ORDER_BY, 0 );
                if ( orderByIndex > 0 ) {
                    // ORDER BY requires using TOP.
                    addTopExpression( sb );
                }
    
                encloseWithOuterQuery( sb );
    
                // Wrap the query within a with statement:
                sb.insert( 0, "WITH query AS (" ).append( ") SELECT " ).append( selectClause ).append( " FROM query " );
                sb.append( "WHERE __hibernate_row_nr__ >= ? AND __hibernate_row_nr__ < ?" );
            }
            else {
                hasOffset = false;
                addTopExpression( sb );
            }
    
            return sb.toString();
        }
    

    设置 page0_、page1_ 和 page2 的私有方法由 fillAliasInSelectClause 完成,执行此操作的摘录是:

    // Inserting alias. It is unlikely that we would have to add alias, but just in case.
    alias = StringHelper.generateAlias( "page", unique );
    

    对我有用的解决方案是在最初没有任何列的 3 列上提供列别名。所以基本上,您需要在所有列上放置别名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-24
      • 2015-09-01
      • 2012-07-15
      • 1970-01-01
      • 1970-01-01
      • 2020-04-15
      相关资源
      最近更新 更多