我将 Spring Boot 2 迁移到版本 3。我使用 Hibernate 6.3.1 Final、Java 17。
迁移后,我的条件查询抛出 InvalidDataAccessResourceUsageException。
@Entity
public class FooEntity {
@Id
private Long id;
@Column
@Lob
private String comment;
...
}
public List<FooEntity> search(FooFilters filters) {
Specification<FooEntity> specification = getSpecification(filters);
return fooRepository.findAll(specification);
}
private Specification<FooEntity> getSpecification(FooFilters filters) {
return (root, query, criteriaBuilder) -> {
List<Predicate> p = new ArrayList<>();
if (StringUtils.isNotBlank(filters.comment())) {
p.add(criteriaBuilder.like(
criteriaBuilder.lower(root.get(FooEntity_.COMMENT)),
"%" + filters.comment() + "%"));
}
return criteriaBuilder.and(p.toArray(Predicate[]::new));
};
}
Foo 是带有注释字段的实体,注释为 @Lob 的字符串。测试在 h2 数据库上运行。 我在没有 @Lob 注释的情况下重新运行测试,它工作正常。
我收到异常:
jakarta.servlet.ServletException: Request processing failed: org.springframework.dao.InvalidDataAccessResourceUsageException: Parameter 1 of function 'lower()' has type 'STRING', but argument is of type 'java.lang.String'
root.get(FooEntity_.COMMENT)
返回一个“BASIC”类型,从我在您的示例中看到的情况来看,该类型在休眠状态下支持 STRING。
一个快速修复方法是向
java.lang.String
添加特定的演员阵容,如下所示:
root.get(FooEntity_.COMMENT).as(String.class)
通过这样做,您的代码运行不会出现问题。
也许他们是一个更好的解决方案,但这个解决方案正在发挥作用。也许可以在您之前的版本(SB2 中)和新版本(SB3 中的最新版本)之间找到有关 Hibernate CHANGELOG 中
@Lob
更改的一些信息。