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

发布于 2024-10-01 22:06:06 字数 497 浏览 0 评论 0原文

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

但是,这给了我一个例外,即不允许在“:”后面添加空格。我尝试过用反斜杠转义它们,我尝试过通过将它们加倍来转义它们。有什么办法可以真正做到这一点,或者我可以吗?

I'm trying to run a native query through JPA that uses a ':' character. The particular instance is using a MySQL user variable in the 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 

The JPA code:

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

However, this gives me an exception about not being allowed to follow a ':' with a space. I've tried escaping them with backslashes, I've tried escaping them by doubling them up. Is there any way to actually do this, or am I SOL?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

各自安好 2024-10-08 22:06:06

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

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

JPA 将抛出错误,表明我尚未设置命名参数:json。

解决办法:

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

I faced similar experience when using postgresql json function in native JPA query.

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

JPA will throw error that i have not set the named parameter :json.

The solution:

"select * from component where data \\:\\:json ->> ?1 = ?2"
在梵高的星空下 2024-10-08 22:06:06

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

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

PS:如果您使用 Hibernate,HHH- 附加了一个非常旧的补丁第1237章

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

3.6.3 命名参数

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

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

传递给的参数名称
QuerysetParameter 方法
API 不包含“:”前缀。

这不会真正帮助您,但您的情况强烈暗示本机查询中的“:”甚至不应该被考虑(至少没有办法逃避它或禁用它检测)。

I'm not aware of a standard way to escape a colon character in a query that is obviously interpreted as a named parameter prefix, and thus confuses the query parser.

My suggestion would be to create and use SQL functions if possible. Depending on your provider, there might be other options (like using another character and substituting the chosen character by a : in an interceptor) but at least the previous suggestion would keep your JPA code portable across providers.

PS: if you're using Hibernate, there is a very old patch attached to HHH-1237.

Update: There is an "interesting" paragraph in the JPA 1.0 spec about named parameters and native queries:

3.6.3 Named Parameters

A named parameter is an identifier
that is prefixed by the ":" symbol.
Named parameters are case-sensitive.

Named parameters follow the rules for
identifiers defined in Section 4.4.1.
The use of named parameters applies to the Java Persistence query
language, and is not defined for
native queries
. Only positional
parameter binding may be portably used
for native queries.

The parameter names passed to the
setParameter methods of the Query
API do not include the ":" prefix.

This won't really help you but your case is a strong hint that the ":" in native queries shouldn't even be considered (at least not without a way to escape it or disable it detection).

浸婚纱 2024-10-08 22:06:06

我使用 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 

I had the same issue using hibernate-5.6.15.Final and after a bit of debugging i found the way to escape the : character in a native query is adding another : character.

you can try:

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 
笙痞 2024-10-08 22:06:06

试试这个:

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();

Try this:

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文