我正在将 Spring Boot 2.7 应用程序迁移到 3.0,这会将 Hibernate 从 5.6 升级到 6.1,并且我在创建
SElECT ... LIKE
查询时遇到了 JPA 的 Criteria API 的问题。
鉴于以下 JPA
Predicate
:
String searchString = "search string with escaped special chars \\% and \\_";
criteriaBuilder.like(criteriaBuilder.lower(root.get("myColumn")), searchString)
在 Hibernate 5.6 / Spring Boot 2.7 中会生成如下查询:
SELECT ...
FROM ...
WHERE lower(myentity0_.`MyColumn`) like ?
Hibernate 6.1 / Spring Boot 3.0 生成如下查询:
SELECT ...
FROM ...
WHERE lower(m1_0.`MyColumn`) like replace(?, '\\', '\\\\')
我使用的是 MariaDB 10.6。
不幸的是,这种行为破坏了我的应用程序,因为我对搜索字符串进行了一些预处理,其中包括使用
%
和 _
转义特殊字符 \%
和 \_
,以便能够搜索它们。然后 Hibernate 对反斜杠进行双重转义,从而取消转义 %
和 _
。
我找到了一种解决方法,在搜索字符串中使用不同的转义字符,例如
#
,并通过 将此字符传播到查询
criteriaBuilder.like(criteriaBuilder.lower(root.get("myColumn")), searchString, '#')
但是感觉不方便。
是否有可能阻止 Hibernate 自动转义搜索字符串?不幸的是,我没有在迁移指南中找到这种行为。
这是作为 https://hibernate.atlassian.net/browse/HHH-15736 的一部分完成的,并确保转义行为在所有数据库中保持一致。 如果您希望
\
成为转义字符,请使用 进行配置
criteriaBuilder.like(criteriaBuilder.lower(root.get("myColumn")), searchString, '\\')
可能有点晚了,但我遇到了同样的问题并找到了以下解决方案。您应该将查询重写如下:
criteriaBuilder.like(
criteriaBuilder.lower(root.get("myColumn")),
criteriaBuilder.literal(searchString));
我在 hibernate 6.3 文档中找到了 'criteriaBuilder.literal()' 方法。