为什么Hibernate会为此HQL抛出QuerySyntaxException?

时间:2015-11-10 17:01:21

标签: java sql hibernate hql

在使用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会关心有两个连续的命名参数。

这不是一个很大的问题,因为它很容易解决(只需将ascdesc字符串值附加到HQL而不是使用命名的参数),但是令我好奇的是,为什么Hibernate会阻止它(可能只是因为99%的时间顺序命名参数会导致无效的SQL / HQL)。

2 个答案:

答案 0 :(得分:2)

我一直在我的本地进行测试,但是无法使用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));
    }

答案 1 :(得分:0)

根据this问题中接受的答案,您只能在WHERE和HAVING子句中定义参数。

同样的答案也为您提供了一些方法来解决您的问题,但是我会再添加一种方法来实现这一点:

在ORDER BY中使用CASE - WHEN子句,这可以通过以下方式工作:

Exame.find().populate('_perguntas').populate('_perguntas._alternativas');

请注意,在这种方法中,您需要编写所有可能的输入以进行订购。不是很漂亮但非常有用,特别是因为您不需要编写具有不同排序的多个查询,再加上这种方法,您可以使用NamedQueries,这可以通过使用字符串连接以语音方式编写查询来实现。

希望这可以解决你的问题,祝你好运!