You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Jakarta Persistence 3.2.0后LIKE查询谓词失效问题求助

问题原因分析

Jakarta Persistence 3.2.0对LIKE谓词的转义字符处理做了隐性变更:当调用cb.like(expr, value)不带转义参数时,规范实现会自动添加escape ''(空转义字符)。而部分数据库(比如MySQL)在处理空转义字符时,会改变原本的匹配逻辑——原本'bar'能正常匹配'bar',但带escape ''后,数据库会将空字符视为转义符,导致匹配规则异常,无法检索到目标数据。

替代解决方案

针对这个问题,有几种可行的修复方式:

  • 显式指定转义字符
    调用cb.like的重载方法,指定一个不会干扰业务的转义字符(比如\,Java中需转义为\\),这样就不会生成escape '':
Specification<MyEntity> byFoo() {
    return (root, query, cb) -> cb.like(
        root.get(MyEntity_.FOO),
        Specifications.like("bar"),
        '\\' // 显式指定转义字符
    );
}
  • 改用likeIgnoreCase(适配不区分大小写场景)
    如果业务允许不区分大小写匹配,可以直接用cb.likeIgnoreCase,该方法在3.2.0版本中不会自动添加空转义字符:
Specification<MyEntity> byFoo() {
    return (root, query, cb) -> cb.likeIgnoreCase(
        root.get(MyEntity_.FOO),
        Specifications.like("bar")
    );
}
  • 自定义匹配规则,规避默认转义逻辑
    如果不需要转义功能,可根据业务场景直接构建匹配逻辑:

    • 全匹配(无通配符)时,直接用equal替代like:
      Specification<MyEntity> byFoo() {
          return (root, query, cb) -> cb.equal(
              root.get(MyEntity_.FOO),
              "bar"
          );
      }
      
    • 需要通配符时,手动拼接匹配串后显式指定转义字符:
      Specification<MyEntity> byFooWithWildcard() {
          String pattern = "%" + "bar" + "%";
          return (root, query, cb) -> cb.like(
              root.get(MyEntity_.FOO),
              pattern,
              '\\'
          );
      }
      
  • 检查Specifications.like方法实现
    确认你的Specifications.like方法是否已在生成匹配字符串时处理了转义逻辑,若已处理,配合显式指定的转义字符即可恢复正常匹配。

内容的提问来源于stack exchange,提问作者Mena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 17:22:26