Hi,
Sory for another topic about this but I've been througth this issue for three days by now and can't find a answer in google, hibernate forum or gira. This simple testCase won't pass using Oracle database and Hibernate 3.2.2. Is there any wrong assumptions made here?
Code:
public void setUp() throws Exception {
Transaction tx = HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Collection all = session.createQuery("from DataObject").list();
for(Object o : all) {
session.delete(o);
}
session.flush();
for(int i=0;i<20;i++) {
DataObject dto = new DataObject(new Long(i+1L));
dto.setStringField("D " + (i+1));
dto.setOtherStringField("Desc " + (i+1));
if (i<3) {
dto.setBooleanStringField("N");
} else {
dto.setBooleanStringField("S");
}
session.save(dto);
}
tx.commit();
}
public void testOraclePaginationError() {
// Start a unit of work
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
List result1,result2;
//Only happens with some kind of ordering
String hql = "select p0 from DataObject p0 order by p0.booleanStringField asc";
Query q = session.createQuery(hql);
//First page
q.setFirstResult(0);
q.setMaxResults(10);
q.setFetchSize(10);
result1 = q.list();
//Second page
q = session.createQuery(hql);
q.setFirstResult(10);
q.setMaxResults(10);
q.setFetchSize(10);
result2 = q.list();
for(Object o : result2) {
log.info("Testing: " + o);
assertFalse(result1.contains(o)); //wont pass!!!
}
}
The pages sholdn't contain the same objects since they are ordered. Examining the generated SQL we can see why. For the first page the SQL looks like this:
Code:
select * from (<QUERY>) where rownum <= X
For the second page the SQL is generated in this form:
Code:
select * from ( select row_.*, rownum rownum_ from ( <QUERY> row_ ) where rownum_ <= X and rownum_ > Y
This disciction leads to the problem described (entities that appear in the first page also appear in subsequent pages). Isn't the case of changing the generated SQL to the second form for every Query that uses the methods setMaxResults/setFirstResult ? Is there any form of doing this "ajustment"?
Any help on this is much appreciated as it's being used in all use cases in a large projetct and we can't afford changing the persistence layer to other framework or use pure JDBC.