24

我正在使用休眠。我写了一些本机查询,因为我需要使用 sub select 语句。

查询如下所示:

SELECT sub.rownum FROM 
    (SELECT k.`news_master_id` AS id, @row := @row + 1 AS rownum 
        FROM keyword_news_list k 
        JOIN (SELECT @row := 0) r 
        WHERE k.`keyword_news_id` = :kid
    ORDER BY k.`news_master_id` ASC) AS sub 
WHERE sub.id  = :nid

当我像这样运行此查询时:

sessionFactory.getCurrentSession()
    .createSQLQuery(query)
    .setParameter("kid", kid)
    .setParameter("nid", nid)
    .uniqueResult();

出现此异常:

org.hibernate.QueryException: Space is not allowed after parameter prefix ':' ....

这可能是因为:=运营商。我发现了一些关于这个的Hibernate 问题。这个问题仍然是开放的。这个问题没有解决办法吗?

4

7 回答 7

31

请注意,HHH-2697现在已针对 Hibernate 4.1.3 修复,您现在可以使用反斜杠转义:

SELECT k.`news_master_id` AS id, @row \:= @row + 1 AS rownum 
    FROM keyword_news_list k 
    JOIN (SELECT @row \:= 0) r 
    WHERE k.`keyword_news_id` = :kid
ORDER BY k.`news_master_id` ASC
于 2012-07-29T13:03:39.237 回答
19

对于我们这些无法跳转到 Hibernate 4.1.3 的人来说,这是另一种解决方案。
只需/*'*/:=/*'*/在查询中使用。Hibernate 代码将两者之间的所有内容'视为字符串(忽略它)。另一方面,MySQL 将忽略块引用中的所有内容,并将整个表达式评估为赋值运算符。
我知道它又快又脏,但它可以在没有存储过程、拦截器等的情况下完成工作。

于 2014-08-28T14:58:01.417 回答
5

你可以实现这是一种稍微不同的方式..你需要用其他东西替换 : 运算符(比如 '|' char )并在你的拦截器中替换 '|' 与 : 。

这样hibernate不会试图认为 : 是一个参数,但会忽略它

拦截器逻辑可以参考hibernate手册

这对我使用 MySQL 5 有效。

请记住,必须仅对 ':=' 和其他 MySQL 特定要求进行此替换。不要尝试替换参数占位符的 :。(然后休眠将无法识别参数)

于 2012-02-27T08:23:29.437 回答
0

我更喜欢包含 Spring JDBC 并执行查询,而不是与 Hibernate 拦截器作斗争。

于 2013-07-04T16:46:19.183 回答
0

遇到 mysql 的 Hibernate 异常中:= operator Stanislav提供了拦截器以外的另一个选项来解决此问题

于 2015-10-21T07:08:07.120 回答
0

如果你让你的 SQL 文件远离 Java 代码——试试这段代码。为了获得正确数量的转义斜线,做了很多工作:

String sqlPattern = FileUtils.readFile(this.getClass(), /sql/my_query.sql");
sqlPattern = sqlPattern.replaceAll(":=", "\\\\:=");
Query query = entityManager.createNativeQuery(sqlPattern);
于 2020-12-03T19:05:17.007 回答
-6

我猜 = 后面不应该有空格,操作符应该写成 =: (没有空格)

于 2012-02-27T04:42:01.213 回答