尝试使用现有的条件构建器复制计数时,在Hibernate 6中似乎会出现以下错误,但在Hibernate 5中似乎可以正常工作。
原因是:java.lang.IllegalArgumentException: Already registered a copy:
原因是:java.lang.IllegalArgumentException: Already registered a copy:
SqmBasicValuedSimplePath(com.example.domain.Test(175781908930100).name)
添加完整代码。
public static <Q, R> Page<Q> getResultsPage(final EntityManager entityManager, final CriteriaQuery<Q> criteria, final Root<R> root, final Pageable pageable,
final List<Order> defaultOrderList) {
return PageableExecutionUtils.getPage(getResultList(entityManager, criteria, root, pageable, defaultOrderList), pageable, () -> count(entityManager, criteria));
}
public static <Q, R> List<Q> getResultList(final EntityManager entityManager, final CriteriaQuery<Q> criteria, final Root<R> root, final Pageable pageable,
final List<Order> defaultOrderList) {
CriteriaUtils.setOrderBy(entityManager, criteria, root, pageable, defaultOrderList);
TypedQuery<Q> resultQuery = entityManager.createQuery(criteria);
if (Objects.nonNull(pageable) && pageable.isPaged()) {
resultQuery.setFirstResult((int) pageable.getOffset()).setMaxResults(pageable.getPageSize());
}
return resultQuery.getResultList();
}
public static <T> Long count(EntityManager em, CriteriaQuery<T> criteria) {
return em.createQuery(countCriteria(em, criteria)).getSingleResult();
}
public static <T> CriteriaQuery<Long> countCriteria(EntityManager em, CriteriaQuery<T> criteria) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Long> countCriteria = builder.createQuery(Long.class);
copyCriteriaWithoutSelectionAndOrder(criteria, countCriteria);
Expression<Long> countExpression;
if (criteria.isDistinct()) {
countExpression = builder.countDistinct(findRoot(countCriteria, criteria.getResultType()));
} else {
countExpression = builder.count(findRoot(countCriteria, criteria.getResultType()));
}
return countCriteria.select(countExpression);
}
private static void copyCriteriaWithoutSelectionAndOrder(
CriteriaQuery<?> from, CriteriaQuery<?> to) {
// Copy Roots
for (Root<?> root : from.getRoots()) {
Root<?> dest = to.from(root.getJavaType());
dest.alias(getOrCreateAlias(root));
copyJoins(root, dest);
}
to.groupBy(from.getGroupList());
to.distinct(from.isDistinct());
if (from.getGroupRestriction() != null)
to.having(from.getGroupRestriction());
Predicate predicate = from.getRestriction();
if (predicate != null)
to.where(predicate);
}