Since this isn't supported by default, I started doing some testing, and my suggestion isn't acceptable.
Code:
Session session = SpringSupport.getSession() ;
long startTime = System.currentTimeMillis() ;
mLogger.warn(Float.toString(this.secondsLater(startTime))) ;
Criteria criteria = session.createCriteria(MyCustomObject.class) ;
criteria.setFetchSize(25) ;
mLogger.warn(Float.toString(this.secondsLater(startTime))) ;
ScrollableResults results = criteria.scroll() ;
mLogger.warn(Float.toString(this.secondsLater(startTime))) ;
// Move to the end
results.last() ;
mLogger.warn(Float.toString(this.secondsLater(startTime))) ;
int lastRow = results.getRowNumber() ;
mLogger.warn(Float.toString(this.secondsLater(startTime))) ;
mLogger.debug("Last row is " + lastRow) ;
Produces the following output:
Code:
15:18:47 [main] WARN p2p.dao.HibernatePaginationTest.testScrollableTime(HibernatePaginationTest.java:28) 0.0
15:18:47 [main] WARN p2p.dao.HibernatePaginationTest.testScrollableTime(HibernatePaginationTest.java:31) 0.016
15:18:52 [main] WARN p2p.dao.HibernatePaginationTest.testScrollableTime(HibernatePaginationTest.java:34) 4.985
15:18:52 [main] WARN p2p.dao.HibernatePaginationTest.testScrollableTime(HibernatePaginationTest.java:37) 5.0
15:18:52 [main] WARN p2p.dao.HibernatePaginationTest.testScrollableTime(HibernatePaginationTest.java:39) 5.016
15:18:52 [main] DEBUG p2p.dao.HibernatePaginationTest.testScrollableTime(HibernatePaginationTest.java:41) Last row is 589823
So that's a 5 second wait for the scroll() call to return.
My good friend Tim Collins has a very elegant solution, that is database independant. He suggests executing the query twice once for the data set, and a second time only returning count(*) for the number of rows.
I'm going to attempt to show that I'm just as smart as Tim Collins, and try to incorporate this into a cached Criteria, or a CountProjection if I can figure out what the hell it does, due to the lack of Javadocs.
I'll post results here.