hibernate - 当使用 spring-data-jpa 2.6.2 的 java.sql.Timestamp 查询 IS NULL 时,hsqldb 中转换的不兼容数据类型

标签 hibernate spring-data-jpa timestamp hsqldb

spring-boot-starter-data-jpa 2.6.4 依赖于 spring-data-jpa 2.6.2,后者依赖于 hsqldb 2.5.2 和 hibernate 5.6.7.Final

当我们想在 CrudRepository 中查询类型为 java.sql.Timestamp 的多个值时,即

@Query("SELECT dm " +
        " FROM DataModel dm " +
        "WHERE (dm.ts1 IS NULL OR :ts1 IS NULL OR dm.ts1 < :ts1) " +
        "  AND (dm.ts2 IS NULL OR :ts2 IS NULL OR dm.ts2 < :ts2)")
List<DataModel> findByTimestamps(@Param("ts1") Timestamp ts1, @Param("ts2") Timestamp ts2);

它失败了 org.hsqldb.HsqlException:转换中不兼容的数据类型

spring-data-jpa 2.6.3 也会发生这种情况

降级到 hsqldb 2.5.1 有效

重现 repo : https://github.com/daveyx/spring-data-hsqldb-timestamp-issue

问题出现在 org.hsqldb.jdbc.JDBCPreparedStatement#setTimestamp(int, java.sql.Timestamp, java.util.Calendar) 中,因为参数类型错误。

在 JDBCPreparedStatement#setTimestamp 中,@Param 注释参数的“IS NULL”部分似乎导致“CharacterType”而不是“DateTimeType”。

最佳答案

如您所述,问题是由条件 OR :ts1 IS NULLOR :ts2 IS NULL 引起的。 Hibernate 以 ? 的形式将这些应用于 SQL 查询。 IS NULL 并且 HSQLDB 将参数解析为字符串。 Hibernate 然后假定参数类型已解析为 java.sql.Timestamp 并调用 setTimestamp(int, Timestamp) 方法,这导致了问题。

您可以添加 CAST 来确定参数的类型。

@Query("SELECT dm " +
    " FROM DataModel dm " +
    "WHERE (dm.ts1 IS NULL OR CAST(:ts1 AS TIMESTAMP) IS NULL OR dm.ts1 < :ts1) " +
    "  AND (dm.ts2 IS NULL OR CAST(:ts2 AS TIMESTAMP) IS NULL OR dm.ts2 < :ts2)")

HSQLDB 版本 2.5.1 对 setTimestamp(int, Timestamp) 很宽松,当目标不是时间戳时将时间戳转换为字符串。版本 2.5.2 和 2.6.0 中的回归使其变得严格。 HSQLDB 的 future 版本将恢复为宽松的方法。

关于hibernate - 当使用 spring-data-jpa 2.6.2 的 java.sql.Timestamp 查询 IS NULL 时,hsqldb 中转换的不兼容数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71836247/

相关文章:

java - spring data jpa stackoverflow错误

java - Spring Data JPA 中的 @Query 注释可以接受枚举列表吗?

javascript - 在javascript中将时间戳转换为人类日期的函数

postgresql - Postgres : incorrect sorting if timestamp in smtp format

hibernate - 如何在 Grails 中应用 Java lambda 表达式过滤

java - 如何在 Spring Boot 控制台应用程序中验证实体?

java - Grails 消息 : No such property: for class: solutions:

Javascript 更改时间戳格式

java - 将 Hibernate 搜索与 RabbitMQ 集成以实现分布式后端

java - Hibernate中自动应用字段转换功能