How to calculate the number of rows of JPA 2 criteriaquery in a general JPA Dao?

I am a novice in JPA. To implement a general JPA Dao, I need to find the number of rows in the query result set to realize paging After searching the Internet, I couldn't find a practical way The following code is recommended in many articles:

public <T> Long findCountByCriteria(CriteriaQuery<?> criteria) {
    CriteriaBuilder builder = em.getCriteriaBuilder();

    CriteriaQuery<Long> countCriteria = builder.createQuery(Long.class);
    Root<?> entityRoot = countCriteria.from(criteria.getResultType());
    countCriteria.select(builder.count(entityRoot));
    countCriteria.where(criteria.getRestriction());

    return em.createQuery(countCriteria).getSingleResult();
}

However, this code does not work when using join Is there a way to calculate the number of rows in the query result set using the JPA criteria API?

Update: This is the code to create the criteriaquery:

CriteriaQuery<T> queryDeFinition = criteriaBuilder.createQuery(this.entityClass);
    Root<T> root = queryDeFinition.from(this.entityClass);

And you can add some joins to the root until the query is executed:

public Predicate addPredicate(Root<T> root) {
                Predicate predicate = getEntityManager().getCriteriaBuilder().ge(root.join(Entity_.someList).get("id"),13);
                return predicate;
}

And the generated exceptions are as follows:

Generatedlias1 should be on the entity, and generatedlias0 should be on the association I joined Note that I implemented the join correctly because when I execute a query without a count query, it executes without errors and the join works normally, but it throws an exception when I try to execute a count query

Solution

I did this:

public Long getRowCount(CriteriaQuery criteriaQuery,CriteriaBuilder criteriaBuilder,Root<?> root){
    CriteriaQuery<Long> countCriteria = criteriaBuilder.createQuery(Long.class);
    Root<?> entityRoot = countCriteria.from(root.getJavaType());
    entityRoot.alias(root.getAlias());
    doJoins(root.getJoins(),entityRoot);
    countCriteria.select(criteriaBuilder.count(entityRoot));
    countCriteria.where(criteriaQuery.getRestriction());
    return this.entityManager.createQuery(countCriteria).getSingleResult();
}

private void doJoins(Set<? extends Join<?,?>> joins,Root<?> root_){
    for(Join<?,?> join: joins){
        Join<?,?> joined = root_.join(join.getAttribute().getName(),join.getJoinType());
        doJoins(join.getJoins(),joined);
    }
}

private void doJoins(Set<? extends Join<?,Join<?,?> root_){
    for(Join<?,joined);
    }
}

Of course, you don't need root as an input parameter. You can get it from the condition query,

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>