6

I'm having trouble figuring out how to represent the following JPQL query:

SELECT count(e) FROM Foo e

using Criteria API. 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));

but this is not working. I also tried:

c.select(cb.count(f.get("id"));

This is for JPA2, Eclipselink.

Tim
  • 6,851
  • 11
  • 42
  • 46

2 Answers2

11

try this, this is working with hibernate 3.5.1:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> c = cb.createQuery(Long.class);
Root<Foo> f = c.from(Foo.class);
c.select(cb.count(f));
int count = em.createQuery(c).getSingleResult().intValue();
cdmckay
  • 31,832
  • 25
  • 83
  • 114
Buchi
  • 126
  • 1
  • 3
5

This is a pretty old question but for completness here's a simple addition:

The title said something about "using countDistinct", so countDistinct should be mentioned here:

CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> critQuery = criteriaBuilder.createQuery(Long.class);
Root<Foo> root = critQuery.from(Foo.class);

critQuery.select(critBuilder.countDistinct(root));
int count = entityManager.createQuery(critQuery).getSingleResult().intValue();

This is important if you don't want to count rows that are double. If you want to avoid doule rows in your ResultList, you'd had to use:

CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> critQuery = criteriaBuilder.createQuery(Long.class);
Root<Foo> root = critQuery.from(Foo.class);

critQuery.select(root).distinct(true);
List<Foo> result = entityManager.createQuery(critQuery).getResultList();
AlexS
  • 5,295
  • 3
  • 38
  • 54