升级至jakarta.persistence-api-3.1.0后CriteriaAPI like谓词行为异常
Jakarta Persistence API 3.1.0中CriteriaBuilder.like失效问题分析与解决
问题现象
升级至jakarta.persistence-api-3.1.0后,以下使用CriteriaBuilder.like的查询返回空结果:
criteriaBuilder.like(file.get("name"), "%" + filename + "%");
甚至旧版本中能返回全部结果的criteriaBuilder.like(file.get("name"), "%")也失效,但criteriaBuilder.equal(file.get("name"), filename)可正常工作。其中file是指向File实体(含name字段)的Path对象,filename为待过滤名称(如"TEST")。
可能原因
- 参数处理逻辑变更:3.1.0版本对
like方法的参数校验更严格,纯通配符或拼接的通配符字符串可能被错误处理,比如被自动转义或判定为无效参数。 - 类型匹配严格性提升:
Path.get("name")返回的属性类型在新版本中未被隐式转换为字符串,导致like的类型匹配失败,而equal方法的类型兼容逻辑未变。 - JPA实现版本不兼容:若底层JPA实现(如Hibernate)未同步升级到支持Jakarta Persistence 3.1的版本,API与实现之间的适配问题会导致
like方法行为异常。
解决方案
- 显式类型转换与字面量包装:将属性显式转为字符串类型,并用
criteriaBuilder.literal包装通配符字符串,确保参数被正确识别:criteriaBuilder.like(file.get("name").as(String.class), criteriaBuilder.literal("%" + filename + "%")); - 同步升级JPA实现:确保使用的JPA实现版本兼容
jakarta.persistence-api-3.1.0,比如Hibernate需升级至6.2及以上版本(Hibernate 6.x全面支持Jakarta Persistence 3.x规范)。 - 显式指定转义字符:调用
like的重载方法指定转义字符,即使没有特殊字符,也能触发正确的参数解析逻辑:criteriaBuilder.like(file.get("name"), "%" + filename + "%", '\\'); - 替换纯通配符查询:若使用
like '%'是为了匹配所有非空值,直接改用isNotNull谓词更可靠,避免新版本对无意义通配符的优化处理:criteriaBuilder.isNotNull(file.get("name"));
内容的提问来源于stack exchange,提问作者Noel93
相关产品推荐
相关产品推荐

