在JPA查询中如何转义冒号字符“:”

31

我正在尝试通过JPA运行使用“:”字符的本地查询。具体实例在查询中使用MySQL用户变量:

SELECT foo, bar, baz, 
    @rownum:= if (@id = foo, @rownum+1, 1) as rownum, 
    @id    := foo                         as rep_id 
FROM 
    foo_table 
ORDER BY 
    foo, 
    bar desc 

JPA代码:

Query q = getEntityManager().createNativeQuery(query, SomeClass.class);
return q.getResultList();

但是,这给了我一个关于不允许在 ':' 后面跟空格的异常。我尝试用反斜杠进行转义,也尝试通过加倍来转义它们。是否有任何方法可以实现这一点,或者我只能无能为力?

4个回答

91

当我在使用本地JPA查询时,使用PostgreSQL JSON函数时,我遇到了类似的经历。

select * from component where data ::json ->> ?1 = ?2

JPA会抛出错误,指出我没有设置命名参数:json。

解决方法:

"select * from component where data \\:\\:json ->> ?1 = ?2"

5
这正是我所需要的,需要将Postgres的JSON转换为字符串并使用::text进行转换。 - GameSalutes
正是我所需要的,谢谢,我在我的@Query中使用了这个where子句:where update_date \:\:date = :fromDate\:\:date,它起作用了。 - JavaDragon

1

我不知道有没有标准的方法来转义查询中的冒号字符,因为它显然被解释为命名参数前缀,从而混淆了查询解析器。

我的建议是尽可能创建和使用SQL函数。根据您的提供商,可能会有其他选项(例如使用另一个字符并在拦截器中用:替换所选字符),但至少先前的建议将使您的JPA代码在各种提供商之间可移植。

附注:如果您正在使用Hibernate,则有一个非常古老的补丁附加到HHH-1237

更新:JPA 1.0规范中有一个“有趣”的段落,涉及命名参数和本地查询:

3.6.3 命名参数

命名参数是以“:”符号为前缀的标识符。命名参数区分大小写。

命名参数遵循第4.4.1节中定义的标识符规则。命名参数的使用适用于Java持久化查询语言,并未针对本地查询进行定义。只有位置参数绑定可用于本地查询。

传递给Query API的setParameter方法的参数名称不包括“:”前缀。

这并不能真正帮助你,但你的情况强烈暗示本地查询中的“:”甚至不应该被考虑(至少没有一种方法可以转义或禁用它的检测)。


谢谢,Pascal!看起来Hibernate在处理本地查询的命名参数时不太符合规范。我已经找到了另一种解决问题的方法。 - Rob Crawford

0
我在使用hibernate-5.6.15.Final时遇到了同样的问题,经过一番调试,我发现在本地查询中转义冒号字符的方法是添加另一个冒号字符。
你可以尝试一下:
SELECT foo, bar, baz, 
    @rownum::= if (@id = foo, @rownum+1, 1) as rownum, 
    @id    ::= foo                         as rep_id 
FROM 
    foo_table 
ORDER BY 
    foo, 
    bar desc 

-1

试试这个:

String query =
"SELECT foo, bar, baz, 
    @rownum \\\\:= if (@id = foo, @rownum+1, 1) as rownum, 
    @id    \\\\:= foo                         as rep_id 
FROM 
    foo_table 
ORDER BY 
    foo, 
    bar desc  -- escape='\' ";

Query q = getEntityManager().createNativeQuery(query, SomeClass.class);
return q.getResultList();

看起来我需要这样做一次。结果是我需要一个更新的Hibernate版本(4.1.3),然后它可以使用单反斜杠 :) https://dev59.com/I2ox5IYBdhLWcg3wDgTR#9461939 - rogerdpack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接