When trying to copy the Critria builder for the Count, using the existing criteria. seems getting the below error in Hibernate 6, but the same seems working in Hibernate 5.
Caused by: java.lang.IllegalArgumentException: Already registered a copy:
SqmBasicValuedSimplePath(com.example.domain.Test(175781908930100).name)
Adding the full code.
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);
}