I make heavy use of the Criteria API for pagination.
Currently, I am using MySQL 4, with a custom hacked PagenatedCriteria object that provides me extra functionality.
I am able to instruct mysql, when using limit and offset, to provide a count of the number of records found before the limit and offset was found. This requires a select hint within the sql query, and a second query to fetch the total number.
This means that I can do very efficient pagination. I can also know the total number of records matching the where clause.
I wish to change over to PostgreSQL, and stop using this hacked PagenatedCriteria object.
I am happy to run two queries - a count query, and the list query. However, currently the Criteria API can only return a list of entities.
I would love to see a modification to the criteria API to support returning a custom select list.
Something like:
Code:
Criteria.uniqueResult(String selectList) // hibernate 3
Criteria.list(String selectList) // hibernate 2.x
// or even
session.createCriteria(Class entityClass, String selectList)
Then I could use this API like this :Code:
Criteria criteria = session.createCriteria(MyClass.class);
addExpressions(criteria);
// get the count list (executes a sql query)
Integer count = (Integer)criteria.uniqueResult("select count(*)");
// select page
criteria.setMaxResults(10);
criteria.setFirstResult(100);
// get the paged list
List pageOfItems = criteria.list();
I can see that these concepts could be implemented in many ways.
1)
criteria cloning with a mutable selectListCode:
Criteria criteria = session.buildCriteria(MyClass.class);
addExpressions(criteria);
Criteria countCriteria = criteria.clone();
countCriteria.setSelectList("select count(*)");
Integer count = (Integer)countCriteria.list().iterator().next();
List itemsForPage = criteria.list();
2)
user creates a criteria instance per query, with immutable selectListCode:
Criteria countCriteria = session.createCriteria(MyClass.class, "select count(*)");
addExpressions(countCriteria);
Integer count = (Integer)countCriteria.list().iterator().next();
Criteria criteria = session.createCriteria(MyClass.class);
addExpressions(criteria);
criteria.setMaxResults(10);
criteria.setFirstResult(100);
List itemsForPage = criteria.list();
I guess that the minimum addition is the ability to specify the 'select list' for criteria based queries. This will allow use of code that generates expressions to be used for both the count query as well as the list query. In fact it can even be used to generate other aggregates.
I know that there was discussion about (not)introducing a .count() method to the criteria API, could this be a way round it ?
This will also allow returning Object[]s or even a list of a single property of an entity.
Any thoughts / ideas ?