public static<T> Long getRows(final EntityManager em, final CriteriaQuery<T> criteria) {
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Long> countCriteria = cb.createQuery(Long.class);
final Root<T> root = countCriteria.from(cb.getResultType());
countCriteria.select(cb.count(root));
for(final Root<?> rootObj: criteria.getRoots()){
countCriteria.getRoots().add(rootObj);
}
final Predicate whereRes = criteria.getRestriction();
if(whereRes != null){
countCriteria.where(whereRes);
}
final Predicate groupRes = criteria.getGroupRestriction();
if(groupRes != null){
countCriteria.having(groupRes);
}
countCriteria.groupBy(criteria.getGroupList());
countCriteria.distinct(criteria.isDistinct());
return em.createQuery(countCriteria).getSingleResult();
}
}
在上面函数的最后一行升级到 Spring Boot 3、Hibernate 6 后,我在代码中遇到了这个问题。请推荐。TIA
按照这个方法就可以了
ublic Long count() {
var countBuilder = (HibernateCriteriaBuilder) builder; //CriteriaBuilder from class level
var countQuery = countBuilder.createQuery(Long.class);
var subQuery = countQuery.subquery(Tuple.class);
var sqmSubQuery = (SqmSubQuery<Tuple>) subQuery;
var sqmOriginalQuery = (SqmSelectStatement) query; // CriteriaQuery from class level
var sqmOriginalQuerySpec = sqmOriginalQuery.getQuerySpec();
var sqmSubQuerySpec = sqmOriginalQuerySpec.copy(SqmCopyContext.simpleContext());
sqmSubQuery.setQueryPart(sqmSubQuerySpec);
Root<?> subQuerySelectRoot = subQuery.getRoots().iterator().next();
sqmSubQuery.multiselect(subQuerySelectRoot.get("id").alias("id"));
countQuery.multiselect(countBuilder.count(countBuilder.literal(1)));
countQuery.from(sqmSubQuery.distinct(true).orderBy(builder.asc(subQuerySelectRoot.get("id"))));
return entityManager.createQuery(countQuery).getSingleResult();
}
或 研究 这篇文章https://hibernate.atlassian.net/browse/HHH-17410
UPD 我对以前的版本有奇怪的问题(有时它尝试从另一个请求表请求对象),所以现在看起来像:
public Long count(CriteriaBuilder builder, CriteriaQuery query) {
var countBuilder = (HibernateCriteriaBuilder) builder;
var countQuery = countBuilder.createQuery(Long.class);
var subQuery = countQuery.subquery(Tuple.class);
var sqmSubQuery = (SqmSubQuery<Tuple>) subQuery;
var sqmOriginalQuery = (SqmSelectStatement) query;
var sqmOriginalQuerySpec = sqmOriginalQuery.getQuerySpec();
var sqmSubQuerySpec = sqmOriginalQuerySpec.copy(SqmCopyContext.simpleContext());
sqmSubQuery.setQueryPart(sqmSubQuerySpec);
Root<?> subQuerySelectRoot = subQuery.getRoots().iterator().next();
sqmSubQuery.multiselect(subQuerySelectRoot.get("id").alias("id"));
countQuery.multiselect(countBuilder.count(countBuilder.literal(1)));
countQuery.from(sqmSubQuery.distinct(true).orderBy(builder.asc(subQuerySelectRoot.get("id"))));
return entityManager.createQuery(countQuery).getSingleResult();
}
我正在尝试实现上述内容
countQuery.from(sqmSubQuery.distinct(true).orderBy(builder.asc(subQuerySelectRoot.get(“id”))));
我收到错误:
无法解析方法“from(org.hibernate.query.criteria.JpaSubQuery
知道如何解决这个问题吗? 感谢你的帮助。谢谢!