In JPA 2, using a CriteriaQuery, how to count results

前端 未结 7 1163
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-28 19:28

I am rather new to JPA 2 and it\'s CriteriaBuilder / CriteriaQuery API:

CriteriaQuery javadoc

CriteriaQuery in the Java EE 6 tutorial

I would like to

7条回答
  •  南笙
    南笙 (楼主)
    2020-11-28 20:08

    It is a bit tricky, depending on the JPA 2 implementation you use, this one works for EclipseLink 2.4.1, but doesn't for Hibernate, here a generic CriteriaQuery count for EclipseLink:

    public static Long count(final EntityManager em, final CriteriaQuery criteria)
      {
        final CriteriaBuilder builder=em.getCriteriaBuilder();
        final CriteriaQuery countCriteria=builder.createQuery(Long.class);
        countCriteria.select(builder.count(criteria.getRoots().iterator().next()));
        final Predicate
                groupRestriction=criteria.getGroupRestriction(),
                fromRestriction=criteria.getRestriction();
        if(groupRestriction != null){
          countCriteria.having(groupRestriction);
        }
        if(fromRestriction != null){
          countCriteria.where(fromRestriction);
        }
        countCriteria.groupBy(criteria.getGroupList());
        countCriteria.distinct(criteria.isDistinct());
        return em.createQuery(countCriteria).getSingleResult();
      }
    

    The other day I migrated from EclipseLink to Hibernate and had to change my count function to the following, so feel free to use either as this is a hard problem to solve, it might not work for your case, it has been in use since Hibernate 4.x, notice that I don't try to guess which is the root, instead I pass it from the query so problem solved, too many ambiguous corner cases to try to guess:

      public static  long count(EntityManager em,Root root,CriteriaQuery criteria)
      {
        final CriteriaBuilder builder=em.getCriteriaBuilder();
        final CriteriaQuery countCriteria=builder.createQuery(Long.class);
    
        countCriteria.select(builder.count(root));
    
        for(Root fromRoot : criteria.getRoots()){
          countCriteria.getRoots().add(fromRoot);
        }
    
        final Predicate whereRestriction=criteria.getRestriction();
        if(whereRestriction!=null){
          countCriteria.where(whereRestriction);
        }
    
        final Predicate groupRestriction=criteria.getGroupRestriction();
        if(groupRestriction!=null){
          countCriteria.having(groupRestriction);
        }
    
        countCriteria.groupBy(criteria.getGroupList());
        countCriteria.distinct(criteria.isDistinct());
        return em.createQuery(countCriteria).getSingleResult();
      }
    

提交回复
热议问题