When running an HQL query on a Java interface that is implemented by two or more Java Classes, each mapped to a different database table, and using query.setMaxResult, the number of results returned is always maxResult plus two. Using debug, this can be traced to logic in org.hibernate.engine.query.spi.HQLQueryPlan method performList. The problem can be seen fairly easily by inspection when looking at the handling of the variable includedCount. The variable starts at -1, is incremented for each record included, and the loop is existed when includedCount > max. So if the maxResults is 10, the loop will continue until includedCount == 11, which (since it started at -1) will only happen after 12 rows have been included, two more than have been requested
int includedCount = -1; translator_loop: for ( QueryTranslator translator : translators ) { final List tmp = translator.list( session, queryParametersToUse ); if ( needsLimit ) { // NOTE : firstRow is zero-based final int first = queryParameters.getRowSelection().getFirstRow() == null ? 0 : queryParameters.getRowSelection().getFirstRow(); final int max = queryParameters.getRowSelection().getMaxRows() == null ? -1 : queryParameters.getRowSelection().getMaxRows(); for ( final Object result : tmp ) { if ( !distinction.add( result ) ) { continue; } includedCount++; if ( includedCount < first ) { continue; }
combinedResults.add( result ); if ( max >= 0 && includedCount > max ) { // break the outer loop !!! break translator_loop; }
} }
|