我正在使用Hibernate。我写了一些原生查询,因为我需要使用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 issue。这个问题仍然存在。这个问题没有解决办法吗?
答案 0 :(得分:24)
请注意,HHH-2697现在已针对Hibernate 4.1.3修复,并在Hibernate 4.3.8.Final上进行了测试;你必须用反斜杠逃脱:
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
答案 1 :(得分:15)
对于我们这些无法跳转到Hibernate 4.1.3的人来说,这是另一种解决方案
只需在查询中使用/*'*/:=/*'*/
即可。 Hibernate代码将'
之间的所有内容视为字符串(忽略它)。另一方面,MySQL会忽略blockquote中的所有内容,并将整个表达式计算为一个assignement运算符
我知道它快速而且肮脏,但是没有存储过程,拦截器等就可以完成工作。
答案 2 :(得分:5)
你可以实现这是一种稍微不同的方式..你需要用其他东西替换:运算符(比如'|'char)并在你的拦截器中替换'|'与:。
这样,hibernate不会试图认为:是一个参数但是会忽略它
对于拦截器逻辑,您可以参考hibernate manual
这对我使用MySQL 5很有用。
记住,这个替换:必须只对':='和其他MySQL特定的要求做..不要试图替换:为param-placeholders。 (然后hibernate将无法识别params)
答案 3 :(得分:0)
我更喜欢包含Spring JDBC并执行查询而不是对抗Hibernate拦截器。
答案 4 :(得分:0)
答案 5 :(得分:0)
如果您的SQL文件远离Java代码,请尝试这段代码。为了获得正确数量的转义斜杠而发挥了很多作用:
String sqlPattern = FileUtils.readFile(this.getClass(), /sql/my_query.sql");
sqlPattern = sqlPattern.replaceAll(":=", "\\\\:=");
Query query = entityManager.createNativeQuery(sqlPattern);
答案 6 :(得分:-5)
我想在=之后应该没有空格,运算符应该写成= :(没有任何空格)