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

SpringBoot3+Hibernate6.4.4中CriteriaBuilder upper()类型不匹配问题求助

问题解决:Hibernate 6 Criteria API upper() 类型不匹配错误

问题场景

使用Spring Boot 3.x + Hibernate 6.4.4.Final + MySQL,编写JPA Like查询Predicate方法时,遇到错误:

Parameter 1 of function 'upper()' has type 'STRING', but argument is of type 'java.lang.String'

原代码如下:

public static Predicate like(@NotNull CriteriaBuilder c, @NotNull Path<String> path, @NotNull String str) {
    return c.like(c.upper(path),
            "%" + str.toUpperCase().replace("/", "//").replace("_", "/_").replace("%", "/%") + "%", '/');
}

public static Predicate like(@NotNull CriteriaBuilder c, @NotNull Expression<String> expression, @NotNull String str) {
    return c.like(c.upper(expression),
            "%" + str.toUpperCase().replace("/", "//").replace("_", "/_").replace("%", "/%") + "%", '/');
}

问题原因

Hibernate 6对Criteria API的类型检查变得更加严格,直接传入Java层面处理后的字符串(如str.toUpperCase()生成的java.lang.String)作为like方法的参数,会导致Hibernate无法正确映射到数据库的STRING类型,进而触发类型不匹配错误。此外,直接在Java代码中处理字符串大写和转义,也不符合JPA Criteria API的表达式模型设计。

解决方案

通过CriteriaBuilder的API来处理字符串的大写转换和字面量包装,确保所有参数都符合Hibernate的类型要求:

public static Predicate like(@NotNull CriteriaBuilder c, @NotNull Path<String> path, @NotNull String str) {
    // 处理查询字符串的转义逻辑
    String escapedStr = "%" + str.replace("/", "//").replace("_", "/_").replace("%", "/%") + "%";
    // 使用CriteriaBuilder的upper和literal方法包装表达式
    Expression<String> upperPath = c.upper(path);
    Expression<String> upperLiteral = c.upper(c.literal(escapedStr));
    return c.like(upperPath, upperLiteral, '/');
}

public static Predicate like(@NotNull CriteriaBuilder c, @NotNull Expression<String> expression, @NotNull String str) {
    String escapedStr = "%" + str.replace("/", "//").replace("_", "/_").replace("%", "/%") + "%";
    Expression<String> upperExpr = c.upper(expression);
    Expression<String> upperLiteral = c.upper(c.literal(escapedStr));
    return c.like(upperExpr, upperLiteral, '/');
}

关键修改点

  1. 移除Java层面的toUpperCase()调用,改用c.upper(c.literal(escapedStr))让Hibernate在SQL层面处理大写转换,确保类型匹配。
  2. 使用c.literal()将转义后的字符串包装为Expression<String>,符合like方法对表达式类型的要求。
  3. 保留原有的转义逻辑,确保通配符和转义字符的处理正确。

如果上述修改仍未解决问题,可尝试显式指定Path的类型:

Expression<String> upperPath = c.upper(path.as(String.class));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:24:53