Hibernate 6 错误:已注册副本:SqmBasicValuedSimplePath(完全限定类名)

5
尝试使用现有的条件构建器复制计数时,在Hibernate 6中似乎会出现以下错误,但在Hibernate 5中似乎可以正常工作。
原因是: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);
    }


你已经找到解决此问题的方法了吗? - robert trudel
1个回答

2
在Hibernate 6中,似乎不再可能以这种方式在不同的CriteriaQueries之间重用对象。我们在CriteriaQueries中遇到了这个错误,在其中将谓词从一个查询复制到另一个查询,并且修复方法是重构代码,使每个CriteriaQuery都创建一个新的Predicate对象(请参见类似问题上我的答案)。不幸的是,在这里看起来你要做的会更困难 - 也许你可以使用这里讨论的SQM复制功能

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接