使用SELECT中的构造函数表达式的JPQL / Hibernate限制

时间:2013-04-04 20:27:50

标签: hibernate select jpa constructor jpql

从我对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

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

1 个答案:

答案 0 :(得分:2)

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

接下来,我在Hibernate上找到了similar 2008-year bug。这些查询也可以在EclipseLink上运行。

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

文档says

  

JPQL是一个受HQL影响很大的子集。 JPQL查询始终是有效的HQL查询,但反之则不然。

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

接下来,查看source file(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