我是JPA的新手,想要实现一个通用的JPA DAO,需要找到查询结果集的行数来实现分页.搜索网络后,我找不到切实可行的方法.以下是许多文章中建议的代码:
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(); }
但是,使用join时该代码不起作用.有没有办法使用JPA Criteria API计算查询结果集的行数?
更新:
这是创建CriteriaQuery的代码:
CriteriaQuery<T> queryDefinition = criteriaBuilder.createQuery(this.entityClass); Root<T> root = queryDefinition.from(this.entityClass);
public Predicate addPredicate(Root<T> root) { Predicate predicate = getEntityManager().getCriteriaBuilder().ge(root.join(Entity_.someList).get("id"),13); return predicate; }
并且生成的异常如下:
org.hibernate.hql.ast.QuerySyntaxException: Invalid path:
‘generatedAlias1.id’ [select count(generatedAlias0) from entity.Entity
as generatedAlias0 where ( generatedAlias0.id>=13L ) and (
(generatedAlias1.id<=34L ) )]
其中generatedAlias1应该在Entity上,generatedAlias0应该在我加入的关联上.
请注意,我正确实现了Join,因为当我执行不带计数查询的查询时,它执行时没有错误,并且Join正常工作但是当我尝试执行count查询时它会抛出异常.
解决方法
我这样做了:
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); } }