Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Using count() with Criteria API

Hello Tim,

If you are going to try using Foo_.id, you need to generate the metamodel classes described here:
http://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_(ELUG)
m.entity(Foo.class) returns the EntityType, not a generated Foo_ class, and so will not have 'id' or any other Foo attributes.
This is why Foo_.getSingularAttribute("id",Integer.class)) will work.

As for the problem with select, you are not posting any exception so I cant be sure, but the query does not look set up correctly. First, when you call:
CriteriaQuery<Foo> c = cb.createQuery(Foo.class);
you are stating that the query results will return instances of Foo - a query using count will not, and should return Long instance(s). The following working example is taken from within the EclipseLink tests that uses the metamodel generation:
       //"SELECT COUNT(DISTINCT phone.owner) FROM PhoneNumber phone";
       CriteriaBuilder qb = em.getCriteriaBuilder();
       CriteriaQuery<Long> cq = qb.createQuery(Long.class);
cq.select(qb.countDistinct(cq.from(getEntityManagerFactory().getMetamodel().entity(PhoneNumber.class)).get(PhoneNumber_.owner)));

A similar test not using the metamodel generation does the same thing, only much more simply:
       //"SELECT COUNT(DISTINCT phone.owner) FROM PhoneNumber phone";
       CriteriaBuilder qb = em.getCriteriaBuilder();
       CriteriaQuery<Long> cq = qb.createQuery(Long.class);
cq.select(qb.countDistinct(cq.from(PhoneNumber.class).get("owner")));

Hope this helps

Best Regards,
Chris









Tim McNerney wrote:
I'm having some trouble getting count() working with Criteria API.
What I have right now using JPQL is:

 SELECT count(e) FROM Foo e

What I'm trying is:

 CriteriaBuilder cb = em.getCriteriaBuilder();
 CriteriaQuery<Foo> c = cb.createQuery(Foo.class);
 Root<Foo> f = c.from(Foo.class);
 c.select(cb.count(f));

and also:

 CriteriaBuilder cb = em.getCriteriaBuilder();
 CriteriaQuery<Foo> c = cb.createQuery(Foo.class);
 Root<Foo> f = c.from(Foo.class);
 c.select(cb.count(f.get("id")));

Ideally, I'd like to get it working with Metamodel, but I've run into
even more problems with that:

 CriteriaBuilder cb = em.getCriteriaBuilder();
 CriteriaQuery<Foo> c = cb.createQuery(Foo.class);
 Root<Foo> f = c.from(Foo.class);
 Metamodel m = em.getMetamodel();
 EntityType<Foo> Foo_ = m.entity(Foo.class);
 c.select(cb.count(f.get(Foo_.id)));

as "id" is not resolved. I do get at least the get part to work with:

 c.select(cb.count(q.get(Foo_.getSingularAttribute("id",Integer.class))));

I still get a failure on select() as it does not resolve to Selection.
I'd still like to use the previous entry as I don't like having use a
string for the column name.

What am I doing wrong with count()? How can I emulate the JPQL query?
Why isn't the Metamodel EntityType not including the attributes? How
can I get them there so I can avoid using string names to get them?

I'm using Eclipselink 2.0.1.

--Tim
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


Back to the top