Java Criteria Query with Hibernate - 生成的别名无效路径?

Posted

技术标签:

【中文标题】Java Criteria Query with Hibernate - 生成的别名无效路径?【英文标题】:Java Criteria Query with Hibernate - generated alias invalid path? 【发布时间】:2021-05-02 15:33:48 【问题描述】:

我有以下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]

什么可能导致这个错误?

【问题讨论】:

您可以尝试更新您的休眠版本并检查一下,这会有所帮助 这不起作用 最新版本是Hibernate 5.4.x。您尝试了哪个版本? 我认为问题在于谓词是由不同的 CriteriaBuilder(不同的别名)创建的 是的,问题在于创建谓词的根,您必须确保它与查询中使用的根相同。也许最好的选择是在 getSearchResults 中创建 de 谓词并重写方法以另一种方式获取条件。 【参考方案1】:

具有讽刺意味的是,几天前我刚刚遇到了完全相同的问题:问题是您的路径“generatedAlias1.title”在 JPQL 中可以理解为从引用的内部实体中取消引用字段 title 生成的别名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;

您将在哪里将方法 getSearchResults 的属性 from 作为参数 root 传递,并将包含“generatedAlias1.title”的字符串作为属性名;然后您可以将您的谓词重新声明为 Predicate 的实例,该实例在此处返回的此路径上起作用。

我希望我已经足够清楚了

【讨论】:

【参考方案2】:

尝试检查您的查询

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

【讨论】:

以上是关于Java Criteria Query with Hibernate - 生成的别名无效路径?的主要内容,如果未能解决你的问题,请参考以下文章

HQL和Criteria

hibernate的Criteria Query(转)

Hibernate 中Criteria Query查询详解

JPA Criteria Query distinct

分享知识-快乐自己:Hibernate 中Criteria Query查询详解

hibernate里‘query’和‘ Criteria’分别啥时候用