-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: creating a select count(*) expression with JPA criteria
PostPosted: Thu May 27, 2010 4:33 pm 
Newbie

Joined: Mon Jan 18, 2010 10:30 am
Posts: 5
I need to build a select count(*) expression using JPA criteria.

I know HQL supports this kind of query

select country, count(*)
from census c
group by c.country

I don't know how to create a count(*) expression using the JPA CriteriaBuilder.

The JPA builder has a count method
Expression<java.lang.Long> count(Expression<?> x)
Create an aggregate expression applying the count operation.

However you have to pass an expression that denotes *.

I know I can do

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> q = cb.createQuery(Long.class);
Root<Census> c = q.from(Census.class);
Expression<Country> exp = c.get(Census_.country);
q.groupBy(exp);
q.select(exp, cb.count(exp));

but I would like to build a generic piece of code that given any expression can count the number of results per group. If the expression is something exp = (employee.salary / 10000 * 10000) then the count will not work, even if the groupBy does.

So in short I would like to do this

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> q = cb.createQuery(Long.class);
Root<Census> c = q.from(Census.class);
Expression<Country> exp = c.get(Census_.country);
q.groupBy(exp);
q.select(exp, cb.count('*'));

But unfortunately any attempt at putting a literal in the count expression results in hql like this

select count(:param0) from Census c where ..

What I did to work around this issue is to sub-class the LiteralExpression and override the render method to return "*". This results in the following HQL

select count(*) from Census c where ..

Is there a better solution?
Thanks
jean-claude


Top
 Profile  
 
 Post subject: Re: creating a select count(*) expression with JPA criteria
PostPosted: Fri Dec 17, 2010 10:50 am 
Newbie

Joined: Thu Dec 16, 2010 3:03 pm
Posts: 2
Thanks for your post. I've also been having a problem with this. I found that you can do
Code:
CriteriaBuilder builder = emf.getCriteriaBuilder();
CriteriaQuery cQuery = builder.createQuery(Integer.class);
Root<X> root = cQuery.from(X.class);
cQuery.select(builder.count(root));


But the resulting HQL looks like
Quote:
select count(X0_.id) as col_0_0_ from X story0_


Depending on your database server and engine, this might be optimized (because the ID is always non-null, counting on the ID is the same as counting *), but in my particular case (MySQL and MyISAM), this doesn't appear to be the case. Fortunately, your work-around seems to do the trick.

I think that this is more a problem of the JPA API then a problem with Hibernate's implementation. They ought to define a method like builder.countAll(), or builder.countStar().


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.