I'm using hibernate and the JPA criteria API and trying to create a re-usable utility method to determine how many rows a query will return.
Currently I have this:
Long countResults(CriteriaQuery cq, String alias){
CriteriaBuilder cb = em().getCriteriaBuilder();
CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
Root ent = countQuery.from(cq.getResultType());
ent.alias(alias);
countQuery.select(cb.count(ent));
Predicate restriction = cq.getRestriction();
if(restriction != null){
countQuery.where(restriction);
}
return em().createQuery(countQuery).getSingleResult();
}
Which I use like this:
CriteriaBuilder cb = em().getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(modelClass());
root.alias("ct");
cq.select(root);
TypedQuery<User> query = em().createQuery(cq);
long count = countResults(cq, "ct");
And that works fine. However, when I use a more complicated query like
Join<UserThing, Thing> j = root.join(User_.things).join(UserThing_.thing);
cq.where(somePredicate);
My call to countResults()
produces exceptions like org.hibernate.hql.internal.ast.InvalidPathException: Invalid path: 'myAlias.name'
, <AST>:0:0: unexpected end of subtree
, left-hand operand of a binary operator was null
I'm guessing this has something to do with the join, and that I need to alias that somehow, but I've not had any success so far.
Help?
I had the same problem, and I solved with:
CriteriaQuery<Long> countCriteria = cb.createQuery(Long.class);
Root<EntityA> countRoot = countCriteria.from(cq.getResultType());
Set<Join<EntityA, ?>> joins = originalEntityRoot.getJoins();
for (Join<EntityA, ?> join : joins) {
countRoot.join(join.getAttribute().getName());
}
countCriteria.select(cb.count(countRoot));
if(finalPredicate != null)
countCriteria.where(finalPredicate);
TypedQuery<Long> queryCount = entityManager.createQuery(countCriteria);
Long count = queryCount.getSingleResult();
Where
originalEntityRoot is the main root where I did the query with the where clauses.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.