使用 Hibernate 的 Java 标准查询 - 生成的别名无效路径?

问题描述

我有以下 java 代码,它使用 hibernate 谓词从我的约会 MysqL 表中返回搜索结果

public List<Appointment> getSearchResults(String client,AppointmentSearchRequest searchRequest,Predicate completePredicate) {

    List<Appointment> searchResults = new ArrayList<>();
    EntityManager entityManager = null;

    try {
        entityManager = entityManagement.createEntityManager(client);
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Appointment> query = builder.createquery(Appointment.class);
        Root<Appointment> from = query.from(Appointment.class);
        CriteriaQuery<Appointment> selectQuery = query.select(from);
        selectQuery = selectQuery.where(completePredicate);

        searchResults = entityManager.createquery(selectQuery).setFirstResult(searchRequest.getIndex()).setMaxResults(searchRequest.getSize()).getResultList();
    }catch (Exception e){
       //
    }

    return searchResults;
}

当我运行此代码时,在以下行:

searchResults = entityManager.createquery(selectQuery).setFirstResult(searchRequest.getIndex()).setMaxResults(searchRequest.getSize()).getResultList();

我收到错误

17:20:27,730 ERROR [org.hibernate.hql.internal.ast.ErrorCounter] (http-/127.0.0.1:8080-2) Invalid path: 'generatedalias1.title'
17:20:27,734 ERROR [org.hibernate.hql.internal.ast.ErrorCounter] (http-/127.0.0.1:8080-2) Invalid path: 'generatedalias1.title':  Invalid path: 'generatedalias1.title'
    at org.hibernate.hql.internal.ast.util.LiteralProcessor.lookupConstant(LiteralProcessor.java:119) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]

可能导致此错误的原因是什么?

解决方法

尝试检查您的查询

this answer。它可能就像检查您的查询别名一样简单。确保它们匹配,否则查询将根本无法编译。你没有在这里列出你的完整查询,所以我不知道它是否不正确。

,

具有讽刺意味的是,几天前我刚刚遇到了完全相同的问题:问题在于您的路径“generatedAlias1.title”,这在 JPQL 中是可以理解的,因为它是从引用为生成的别名1

不幸的是,CriteriaBuilder 无法理解单个字符串中的这个复杂路径。

此路径通常在 Predicate 元素中描述,您在此处将其作为参数传递给您的方法 getSearchResults,名称为 completePredicate ...(问题在于您没有告诉我们你是如何创建这个谓词的)

所以你需要重构你声明这个路径的方式,最终使用类 javax.persistence.criteria.Path 并用这个方法计算它

final private <V> Path<V> getPath(Root<T> root,String attributeName) {
        Path<V> path = null;
        for (String part : attributeName.split("\\.")) {
            path = (path == null) ? root.get(part) : path.get(part);
        }
        return path;
}

您将方法的 from 属性作为参数 root 传递,并将包含“generatedAlias1.title”的字符串作为参数传递属性名称;那么你可以重新声明你的谓词作为一个 Predicate 的实例,它作用于这里返回的这条路径。

我希望我已经足够清楚