我正在从 Spring Boot 2.7 迁移到 3.2,在尝试使用 Spring Data 和 Hibernate 运行本机查询时,我最终出现以下错误:
Caused by: org.hibernate.exception.SQLGrammarException: JDBC exception executing SQL [
SELECT *
FROM myTable
WHERE (? IS NULL OR my_first_field like ? || '%')
AND (? IS NULL OR my_second_field like ? || '%')
LIMIT ?
] [ERROR: could not determine data type of parameter $3] [n/a]
在我的 JpaRepository 中,查询如下:
@Query(
value =
"""
SELECT *
FROM myTable
WHERE (:myFirstField IS NULL OR my_first_field like :myFirstField || '%')
AND (:mySecondField IS NULL OR my_second_field like :mySecondField || '%')
LIMIT :limit
""",
nativeQuery = true)
List<MyTableEntity> getEntitiesWhereFirstAndSecondFieldsLike(
@Param("myFirstField") String myFirstField,
@Param("mySecondField") String mySecondField,
@Param("limit") int limit);
在这种情况下,错误是由参数“mySecondField”为空触发的。
这个完全相同的查询在 Spring Boot 2.7 中运行得非常好,我感觉我已经阅读了整个迁移指南,但没有找到任何线索。
我可以设置什么来告诉 Hibernate 如何处理空值吗?
对我的数据库(PostgreSql)运行 SQL 查询并将 ':myFirstField' 和 ':mySecondField' 替换为 null 也可以,如果有帮助的话。
转换参数(如下所示)似乎可以解决问题,但我无法对应用程序中的每个本机查询执行此操作,因为这可能需要我相当长的时间,而且根本感觉不是正确的解决方案。
SELECT *
FROM myTable
WHERE ((:myFirstField as text) IS NULL OR my_first_field like :myFirstField || '%')
AND ((:mySecondField as text) IS NULL OR my_second_field like :mySecondField || '%')
LIMIT :limit
发生这种情况是因为最新版本的 Hibernate(Spring Boot 3)需要隐式类型处理。所以尝试像这样使用
CONCAT
SELECT *
FROM myTable
WHERE (:myFirstField IS NULL OR my_first_field LIKE CONCAT(:myFirstField, '%'))
AND (:mySecondField IS NULL OR my_second_field LIKE CONCAT(:mySecondField, '%'))
LIMIT :limit