org.hibernate.sql.ast.SqlTreeCreationException:无法找到TableGroup - model.dao.User(1055362627602899)

Adr*_*ian 10 hibernate hibernate-criteria spring-boot

我有一个 spring boot 2.7.5 和 hibernate 5.6.12 项目,我想升级到 spring boot 3.1.0 和 hibernate 6.6.2 我正在尝试数据库中的查询计数以获取数据库中的记录总数,我得到错误

org.hibernate.sql.ast.SqlTreeCreationException:无法在 org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.prepareReusablePath(BaseSqmToSqlAstConverter.java:3349) ~[hibernate-core- 6.2.2.Final.jar:6.2.2.Final]

基类是:

public class JPADaoImpl {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    
    @Autowired
    @Qualifier("dataSource")
    protected DataSource dataSource;
    
    @PersistenceContext
    protected EntityManager entityManager;
    
    protected <T> PageData<T> getPageData(CriteriaQuery<T> criteria,Root<T> root,Integer pStart, Integer pSize,LockModeType lockModeType) throws Exception{
        PageData<T> pageData =null;
        try {
            pageData = new PageData<T>();
            
            criteria.distinct(true);
            
            criteria.select(root);
            
            TypedQuery<T> query = getPersistenceQuery(criteria, pStart, pSize, lockModeType);
            
            if (pStart == null || pSize == null) {
                pageData.setData(query.getResultList());
                return pageData;
            }
            
            pageData.setpStart(pStart);
            pageData.setpSize(pSize);
            
            Long rowCount = getRowCount(criteria,root,true);
            pageData.setTotalNo(rowCount);

            pageData.setpCount(rowCount / pSize + (rowCount % pSize == 0 ? 0 : 1));
    
            pageData.setData(query.getResultList());
            
            return pageData;
        } catch (Exception e) {
            throw e;
        }
    }
    
    
    /**
     * 
     * @param criteria
     * @param root
     * @param distinct
     * @return
     * @throws Exception
     */
    protected <T> Long getRowCount(CriteriaQuery<T> criteria,Root<T> root,boolean distinct) throws Exception {
        Long rowcount=null;
        CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 
        CriteriaQuery<Long> countCriteria=builder.createQuery(Long.class);
        
        Root<?> entityRoot = countCriteria.from(root.getJavaType());
        entityRoot.alias(root.getAlias());
        
        doJoins(root.getJoins(),entityRoot);
        if( criteria.isDistinct()){
             countCriteria.select(builder.countDistinct(entityRoot));
        }else{
            countCriteria.select(builder.count(entityRoot));
        }
        
        Predicate fromRestriction = criteria.getRestriction();
    
        if (fromRestriction != null) {
            countCriteria.where(fromRestriction);
        }
        
        countCriteria.distinct(criteria.isDistinct());
    
        rowcount=entityManager.createQuery(countCriteria).getSingleResult();

        return rowcount;
    }
    
    /**
     * 
     * @param joins
     * @param root_
     */
    private void doJoins(Set<? extends Join<?, ?>> joins,Join<?,?> root_){
        for(Join<?,?> join: joins){
            Join<?,?> joined = root_.join(join.getAttribute().getName(),join.getJoinType());
            doJoins(join.getJoins(),joined);
        }
    }
    /**
     * 
     * @param joins
     * @param root_
     */
    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);
        }
    }

    
        /**
     * @param criteria
     * @param pStart
     * @param pSize
     * @param lockModeType
     * @return
     */
    private <T> TypedQuery<T> getPersistenceQuery(CriteriaQuery<T> criteria, Integer pStart, Integer pSize, LockModeType lockModeType) {
        
        TypedQuery<T> query = entityManager.createQuery(criteria);
        
        if(lockModeType!=null){
            query.setLockMode(lockModeType);
        }
        
        if (pStart != null && pSize != null) {
            query.setFirstResult((pStart - 1) * pSize);
            query.setMaxResults(pSize);
        }
        return query;
    }

}
Run Code Online (Sandbox Code Playgroud)

以及扩展它的类

public class UserDaoImpl extends JPADaoImpl implements UserDao{
    
    @Override
    public PageData<User> list(User filter, Integer pStart, Integer pSize, List<Order> order, User userAuth) throws Exception {
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<User> criteria = criteriaBuilder.createQuery(User.class);
        Root<User> root = criteria.from(User.class);
        root.alias("root");
        criteria.select(root);
    
        List<Predicate> predicateList = null;
                    
        if (filter!=null){
            
            predicateList = new ArrayList<Predicate>();
            
            if (!Utils.isEmpty(filter.getStatus())) {
                predicateList.add(criteriaBuilder.and(criteriaBuilder.equal(root.<Byte>get("status"),filter.getStatus())));
            }
        }
        
        if(!Utils.isEmpty(predicateList)){
            criteria.where(criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()])));
        }
        criteria.orderBy(criteriaBuilder.asc(root.get("last_name")),criteriaBuilder.asc(root.get("first_name")));
        
        PageData<User> pageData;
    
        pageData = getPageData(criteria,root, pStart, pSize);
        
    
        return pageData;
    }

}
Run Code Online (Sandbox Code Playgroud)

在 UserDaoImpl.list 方法中,JPADaoImpl.getRowCount 行 rowcount=entityManager.createQuery(countCriteria).getSingleResult();

我收到错误

org.hibernate.sql.ast.SqlTreeCreationException:无法在 org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.prepareReusablePath(BaseSqmToSqlAstConverter.java:3349) ~[hibernate-core- 6.2.2.Final.jar:6.2.2.Final]

如果我注释行 countCriteria.where(fromRestriction); 工作正常

它也适用于 Spring Boot 2.7.5 和 Hibernate 5.6.12

难道是新版本hibernate的bug?这是解决这个问题的解决方法吗?

谢谢你,
阿德里安

小智 -1

Predicate fromRestriction = criteria.getRestriction();
// hibernate 5.x
if (fromRestriction != null) {
  countCriteria.where(fromRestriction);
}


 Predicate predicateList= new ArrayList();
 // hibernate 6.x
 if (predicateList!= null) {
   countCriteria.where(predicateList);
 }
Run Code Online (Sandbox Code Playgroud)

  • 通过额外的支持信息可以改进您的答案。请[编辑]添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以[在帮助中心](/help/how-to-answer)找到有关如何写出好的答案的更多信息。 (2认同)