JPA / Hibernate нумерация страниц в MS SQL Server 2008 отображение ошибок на объект

1

Учитывая мой код ниже:

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.

Теги:
hibernate
orm
sql-server-2008
pagination

1 ответ

1
Лучший ответ

Я нашел ответ на этот вопрос. Пользовательский запрос 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 столбцах, которые изначально не были. Таким образом, вам нужно будет поместить псевдоним на все ваши столбцы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню