在JPA查询中转义冒号字符':'

时间:2010-11-12 22:19:33

标签: mysql jpa jpql

我正在尝试通过使用“:”字符的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();

但是,这给了我一个例外,即不允许用空格跟随':'。我已经尝试用反斜杠逃避它们,我已经尝试通过将它们加倍来逃避它们。有没有办法真正做到这一点,还是我是SOL?

3 个答案:

答案 0 :(得分:40)

在本机JPA查询中使用postgresql json function时,我遇到了类似的经历。

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

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

解决方案:

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

答案 1 :(得分:1)

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

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

PS:如果你正在使用Hibernate,那么HHH-1237附有一个非常旧的补丁。

更新: JPA 1.0规范中有一个关于命名参数和本机查询的“有趣”段落:

  

3.6.3命名参数

     

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

     

命名参数遵循规则   第4.4.1节中定义的标识符。   命名参数的使用适用于Java Persistence查询   语言,并没有定义   原生查询。只有位置   可以便携地使用参数绑定   用于原生查询。

     

传递给的参数名称   setParameter的{​​{1}}种方法   API不包含“:”前缀。

这对你没有用,但是你的情况强烈暗示原生查询中的“:”甚至不应该被考虑(至少没有办法逃脱它或禁用它检测)。

答案 2 :(得分:-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();