我有一个 Spring Boot 2.7.5 和 Hibernate 5.6.12 项目,我想升级到 Spring Boot 3.1.0 和 Hibernate 6.6.2 我正在尝试数据库中的查询计数以获取数据库中的记录总数 我收到错误
org.hibernate.sql.ast.SqlTreeCreationException:无法找到TableGroup - model.dao.User(1057834329991800) 在 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;
}
}
以及扩展它的类
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;
}
}
在 UserDaoImpl.list 方法中,JPADaoImpl.getRowCount 行 rowcount=entityManager.createQuery(countCriteria).getSingleResult();
我收到错误
org.hibernate.sql.ast.SqlTreeCreationException:无法找到TableGroup - model.dao.User(1057834329991800) 在 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吗? 有解决这个问题的方法吗?
谢谢你,
阿德里安
就我而言,我改变了填充谓词的方式并且它起作用了:
Predicate[] predicates = {
builder.like(builder.lower(root.get("colunm1")),"%" + numeroProcesso.toLowerCase() + "%"),
root.get("colunm2").in(orgaoJulgadores)
};
criteria.where(predicates);
对于
List<Predicate> predicates = new ArrayList<>();
predicates.add(builder.like(builder.lower(root.get("colunm1")),
"%" + numeroProcesso.toLowerCase() + "%"));
predicates.add(root.get("colunm2").in(orgaoJulgadores));
criteria.where(predicates.toArray(new Predicate[predicates.size()]));
要解决此问题,您应该为计数查询和检索记录的查询创建单独的 CriteriaQuery 对象。每个查询都应该有其自己关联的 Root 对象。这确保了 where 语句中的过滤器引用正确的根来计数和检索记录。
在另一个 CriteriaQuery 的 where 语句中使用来自不同 CriteriaQuery 的根可能会导致“无法找到 TableGroup”错误。此错误表明 Hibernate 难以确定查询的正确表组,可能是由于根不匹配。
这个问题有解决办法吗? 今天我们收到了同样的异常。请帮忙。谢谢!
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);
}