Учитывая мой код ниже:
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();
Где страница> 1, сгенерированная sql неверна:
С запросом AS (SELECT inner_query. *, ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) как hibernate_row_nr FROM (выберите TOP (?) Cc.company_id как page0_, cc.long_name как page1_, cc.reuters_org_id as page2_, ccdom.country_name как country_of_domicile, ccinc.country_name как country_of_incorporation, ccr.region_name как регион, ci.industry_name как индустрия из zz_prp_common_company cc left join zz_prp_common_country ccdom on cc.country_of_domicile = ccdom.country_id left join zz_prp_common_region ccr на ccr.region_id = ccdom.region_id left join zz_prp_common_country ccinc on cc.country_of_domicile = ccinc.country_id left join zz_prp_common_industry ci on cc.industry_id = ci.industry_id где 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 > знак равно И hibernate_row_nr <?
Я не могу понять, почему он заменяет псевдоним на мои столбцы на страницы0_, page1_ и page2_. Из-за этого, где 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.
Я нашел ответ на этот вопрос. Пользовательский запрос sql, который я использовал, не имел ни одного псевдонима в первых трех столбцах (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 столбцах, которые изначально не были. Таким образом, вам нужно будет поместить псевдоним на все ваши столбцы.