[hibernate-issues] [Hibernate-JIRA] Created: (HHH-3542) Polymorphic query with set first row and limit result set returns wrong results
Yevgeny Shakhnovich (JIRA)
noreply at atlassian.com
Thu Oct 23 16:29:04 EDT 2008
Polymorphic query with set first row and limit result set returns wrong results
-------------------------------------------------------------------------------
Key: HHH-3542
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3542
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.2.0.ga
Reporter: Yevgeny Shakhnovich
If we issue a polymorphic query with the specified first row and set max rows to retrieve, the query returns wrong results.
For example, you have two entities A and B implementing the same interface C.
Query query = session.createQuery("from C");
query.setMaxResults(10);
query.setFirstResult(10);
List<Object[]> result = query.list(); // will return only two records despite of tables A and B have enough records
The bug is pretty simple: the same variable is used to count total number of records and included records.This is the excerpt from org.hibernate.engine.query.HQLQueryPlan.performList
int includedCount = -1;
translator_loop: for ( int i = 0; i < translators.length; i++ ) {
List tmp = translators[i].list( session, queryParametersToUse );
if ( needsLimit ) {
// NOTE : firstRow is zero-based
int first = queryParameters.getRowSelection().getFirstRow() == null
? 0
: queryParameters.getRowSelection().getFirstRow().intValue();
int max = queryParameters.getRowSelection().getMaxRows() == null
? -1
: queryParameters.getRowSelection().getMaxRows().intValue();
final int size = tmp.size();
for ( int x = 0; x < size; x++ ) {
final Object result = tmp.get( x );
if ( !distinction.add( result ) ) {
continue;
}
// In example above first is 10 and max is 10 as well.
includedCount++;
if ( includedCount < first ) {
continue;
}
// This point is reached only when includedCount is 10 or more
combinedResults.add( result );
if ( max >= 0 && includedCount > max ) {
// break the outer loop !!!
break translator_loop;
}
The fix is also simple: add one more variable to keep the total number of records:
int includedCount = 0;
int recordCount = 0;
translator_loop: for ( int i = 0; i < translators.length; i++ ) {
List tmp = translators[i].list( session, queryParametersToUse );
if ( needsLimit ) {
// NOTE : firstRow is zero-based
int first = queryParameters.getRowSelection().getFirstRow() == null
? 0
: queryParameters.getRowSelection().getFirstRow().intValue();
int max = queryParameters.getRowSelection().getMaxRows() == null
? -1
: queryParameters.getRowSelection().getMaxRows().intValue();
final int size = tmp.size();
for ( int x = 0; x < size; x++ ) {
final Object result = tmp.get( x );
if ( !distinction.add( result ) ) {
continue;
}
/* includedCount should include only what was really included */
if ( recordCount++ < first) {
continue;
}
includedCount++;
combinedResults.add( result );
if ( max >= 0 && includedCount >= max ) {
// break the outer loop !!!
break translator_loop;
}
}
}
else {
combinedResults.addAll( tmp );
}
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the hibernate-issues
mailing list