为啥 Hibernate 会为此 HQL 抛出 QuerySyntaxException?
Posted
技术标签:
【中文标题】为啥 Hibernate 会为此 HQL 抛出 QuerySyntaxException?【英文标题】:Why does Hibernate throw a QuerySyntaxException for this HQL?为什么 Hibernate 会为此 HQL 抛出 QuerySyntaxException? 【发布时间】:2015-11-10 17:01:21 【问题描述】:在使用 Hibernate 构建查询时,我注意到一些很奇怪的事情。如果我对ORDER BY
子句使用顺序命名参数,Hibernate 会抛出一个QuerySyntaxException
(冒号前缀是一个意外的标记):
createQuery("FROM MyEntity ORDER BY :orderProperty :orderDirection");
但是,如果使用纯 SQL 查询完成此操作,则创建查询时不会出现问题:
createSQLQuery("SELECT * FROM my_entity_table ORDER BY :orderProperty :orderDirection");
我知道 Hibernate 正在对 HQL 查询进行更多的字符串评估,这可能是 SQL 查询创建时没有错误的原因。我只是想知道为什么 Hibernate 会关心有两个连续的命名参数。
这不是一个大问题,因为它很容易解决(只需将 asc
或 desc
字符串值附加到 HQL,而不是为其使用命名参数),但我很好奇为什么Hibernate 正在阻止它(可能仅仅是因为 99% 的时间顺序命名参数像这样导致无效的 SQL/HQL)。
【问题讨论】:
***.com/questions/17510034/… 【参考方案1】:我一直在本地对此进行测试,但使用 HQL 无法获得您想要的结果。
这是我链接的帖子的引用:
您不能将列名绑定为参数。只有一个列值。在计算执行计划、绑定参数值和执行查询之前,必须知道该名称。如果您真的想要这样的动态查询,请使用 Criteria API 或其他动态创建查询的方式。
Criteria API 看起来对您来说是更有用的工具。
这是一个例子:
Criteria criteria = session.createCriteria(MyEntity.class);
if (orderDirection.equals("desc"))
criteria.addOrder(Order.desc(orderProperty));
else
criteria.addOrder(Order.asc(orderProperty));
【讨论】:
我认为这不会起作用,因为:orderDirection
不是列,它是修改列排序方向的升序/降序字符串值。您的建议会导致 ORDER BY columnName, asc
导致错误,因为 ASC(同样是 DESC)不是列名。
啊,我以为 orderDirection 是一个专栏,那么让我修改一下我的答案。
是的,Criteria 可能效果最好。这是一个简单的转换,让我对它不喜欢的东西有点失望。但我认为你是对的,使用列名作为命名参数是一个问题。即使没有 :orderDirection
参数,它也会失败(查询构建,但生成的实际 SQL 不正确)。感谢您的意见!【参考方案2】:
根据this问题接受的答案,只能在WHERE和HAVING子句中定义参数。
同样的答案也为您提供了一些解决问题的方法,但是我将添加另一种方法:
在您的 ORDER BY 中使用 CASE - WHEN 子句,这将通过以下方式起作用:
SELECT u FROM User u
ORDER BY
CASE WHEN '**someinputhere**' = :orderProperty
AND '**someotherinput**' = :orderDirection
THEN yourColumn asc
ELSE yourColumn desc END
请注意,在这种方法中,您需要编写所有可能的订购输入。不是很漂亮但很有用,尤其是因为您不需要编写具有不同顺序的多个查询,而且通过这种方法,您可以使用 NamedQueries,这可以通过使用字符串连接以动态方式编写查询来实现。
希望这能解决你的问题,祝你好运!
【讨论】:
以上是关于为啥 Hibernate 会为此 HQL 抛出 QuerySyntaxException?的主要内容,如果未能解决你的问题,请参考以下文章
为啥得到 org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join!加入 3 个表时