Like other answers, they are correct, but too simple, so for completeness I present below a code fragment for executing SELECT COUNT in a complex JPA query criteria (with several unions, selections, conditions).
This answer is slightly modified.
public <T> long count(final CriteriaBuilder cb, final CriteriaQuery<T> selectQuery, Root<T> root) { CriteriaQuery<Long> query = createCountQuery(cb, selectQuery, root); return this.entityManager.createQuery(query).getSingleResult(); } private <T> CriteriaQuery<Long> createCountQuery(final CriteriaBuilder cb, final CriteriaQuery<T> criteria, final Root<T> root) { final CriteriaQuery<Long> countQuery = cb.createQuery(Long.class); final Root<T> countRoot = countQuery.from(criteria.getResultType()); doJoins(root.getJoins(), countRoot); doJoinsOnFetches(root.getFetches(), countRoot); countQuery.select(cb.count(countRoot)); countQuery.where(criteria.getRestriction()); countRoot.alias(root.getAlias()); return countQuery.distinct(criteria.isDistinct()); } @SuppressWarnings("unchecked") private void doJoinsOnFetches(Set<? extends Fetch<?, ?>> joins, Root<?> root) { doJoins((Set<? extends Join<?, ?>>) joins, root); } private void doJoins(Set<? extends Join<?, ?>> joins, Root<?> root) { for (Join<?, ?> join : joins) { Join<?, ?> joined = root.join(join.getAttribute().getName(), join.getJoinType()); joined.alias(join.getAlias()); doJoins(join.getJoins(), joined); } } private void doJoins(Set<? extends Join<?, ?>> joins, Join<?, ?> root) { for (Join<?, ?> join : joins) { Join<?, ?> joined = root.join(join.getAttribute().getName(), join.getJoinType()); joined.alias(join.getAlias()); doJoins(join.getJoins(), joined); } }
Hope this saves you some time.
Because the IMHO JPA API is not intuitive or readable.
G. Demecki May 22, '15 at 7:08 2015-05-22 07:08
source share