JPQL/Hibernate limitation using constructor expression in SELECT

怎甘沉沦 提交于 2019-12-22 08:46:25

问题


From my reading of the JPA 2.0 spec, the following should be valid:

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

However, Hibernate complains about this query, citing the first comma. If I reverse the order of the selected expressions, it still complains:

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

But if I select only the constructor expression, it works:

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

I have searched in vain for examples on the web of JPQL queries that use constructor expressions that are not the sole expressions in the SELECT clause, even though the grammar in the JPA 2.0 spec appears to allow them. Does anyone know of a workaround for this, other than to create a different, monolithic custom class that encapsulates all data in a selected record?


回答1:


Tried your query on Hibernate-JPA (org.hibernate.hql.internal.ast.QuerySyntaxException) and on EclipseLink (OK).

Next, I found similar 2008-year bug on Hibernate. Those query also runs OK on EclipseLink.

I think, it is a bug of Hibernate (HQL).

Documentation says,

JPQL is a heavily-inspired-by subset of HQL. A JPQL query is always a valid HQL query, the reverse is not true however.

In fact, Hibernate parses JPQL query with the same grammar/parser as HQL.

Next, look in source file (HQL ANTLR grammar), I see this:

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!
;

So, now it is clear, why Hibernate throws QuerySyntaxException. When using Hibernate JPQL, we are forced to choose one of three options:

  • properties list (i.e. e.employeeName, e.employeeCity)
  • constructor expression (i.e. new com.foo.Custom(e.employeeName, e.employeeCity))
  • object identifier from 'FROM' clause (i.e. e)


来源:https://stackoverflow.com/questions/15821074/jpql-hibernate-limitation-using-constructor-expression-in-select

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!