I am trying to implement the following convenience method:
/**
* Counts the number of results of a search.
* @param criteria The criteria for the query.
* @return The number of results of the query.
*/
public int findCountByCriteria(CriteriaQuery<?> criteria);
In Hibernate, this is done by
criteria.setProjection(Projections.rowCount());
What is the equivalent to the above in JPA? I found numerous simple count examples, but none of them made use of a CriteriaQuery whose row count should be determined.
EDIT:
I unfortunately found out that @Pascal's answer is not the correct one. The problem is very subtle and only shows up when you use joins:
// Same query, but readable:
// SELECT *
// FROM Brain b
// WHERE b.iq = 170
CriteriaQuery<Person> query = cb.createQuery(Person.class);
Root<Person> root = query.from(Person.class);
Join<Object, Object> brainJoin = root.join("brain");
Predicate iqPredicate = cb.equal(brainJoin.<Integer>get("iq"), 170);
query.select(root).where(iqPredicate);
When calling findCountByCriteria(query)
, it dies with the following exception:
org.hibernate.hql.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.iq' [select count(generatedAlias0) from xxx.tests.person.dom.Person as generatedAlias0 where generatedAlias1.iq=170]
Is there any other way to provide such a CountByCriteria
method?
if you want the result and the count of all elements like Spring Data's Page-Element you can do two queries. What you can do is to separate the criteria from the query-execution.
Example to find Users by City
addiional to the getUser Method you can build a second that will count your elements
and the createConditions Method will handle both, so you do not have to duplicate your logic for the criteria.
in your contoller you can do something like
long elementCount = yourCriteriaClassInstance.getElementCount(...); List users = yourCriteriaClassInstance.getUsers(...)