4

根据我对 JPA 2.0 规范的阅读,以下内容应该是有效的:

select e.employeeId, new com.foo.Custom(e.employeeName, e.employeeCity) from Employee e

然而,Hibernate 抱怨这个查询,引用了第一个逗号。如果我颠倒所选表达式的顺序,它仍然会抱怨:

select new com.foo.Custom(e.employeeName, e.employeeCity), e.employeeId from Employee e

但是如果我只选择构造函数表达式,它会起作用:

select new com.foo.Custom(e.employeeName, e.employeeCity) from Employee e

尽管 JPA 2.0 规范中的语法似乎允许使用构造函数表达式,但我在 JPQL 查询的 Web 上搜索了这些示例,但这些示例不是 SELECT 子句中的唯一表达式。除了创建一个将所有数据封装在选定记录中的不同的整体自定义类之外,有没有人知道解决方法?

4

1 回答 1

2

在 Hibernate-JPA ( org.hibernate.hql.internal.ast.QuerySyntaxException) 和 EclipseLink (OK) 上尝试了您的查询。

接下来,我在 Hibernate 上发现了类似的 2008 年 bug 。这些查询也可以在 EclipseLink 上运行。

我认为,这是 Hibernate (HQL) 的一个错误。

文档

JPQL 是一个深受 HQL 启发的子集。JPQL 查询始终是有效的 HQL 查询,但反之则不然。

事实上,Hibernate 使用与 HQL 相同的语法/解析器来解析 JPQL 查询。

接下来,查看源文件(HQL ANTLR 语法),我看到了:

selectClause
: SELECT^   // NOTE: The '^' after a token causes the corresponding AST node to be the root of the sub-tree.
    { weakKeywords(); } // Weak keywords can appear immediately after a SELECT token.
    (DISTINCT)? ( selectedPropertiesList | newExpression | selectObject )
;

newExpression
: (NEW! path) op:OPEN^ {#op.setType(CONSTRUCTOR);} selectedPropertiesList CLOSE!
;

所以,现在很清楚,为什么 Hibernate 会抛出QuerySyntaxException. 使用 Hibernate JPQL 时,我们被迫选择以下三个选项之一:

  • 属性列表(即e.employeeName, e.employeeCity
  • 构造函数表达式(即new com.foo.Custom(e.employeeName, e.employeeCity)
  • 来自“FROM”子句的对象标识符(即e
于 2014-04-27T07:05:38.483 回答