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,
