使用 Spring 数据 JDBC 不支持类型的查询参数?

Using query parameter of type not supported in Spring Data JDBC?

我试图在我的存储库中编写一个类似于此的查询方法

@Modifying
@Query("UPDATE foo SET some_timestamp = :someTimestamp WHERE id = :id")
void updateSomeTimestamp(@Param("id") long id, @Param("someTimestamp") Instant someTimestamp)

执行代码时出现以下错误:

org.postgresql.util.PSQLException:无法推断 SQL 类型用于 java.time.Instant 的实例。使用带有显式类型值的 setObject() 来指定要使用的类型。

我是不是忘记了什么,或者 Spring 数据 Jdbc 根本不支持使用 Instant 作为参数?如果有,未来是否计划提供此类支持?

Spring 数据 JDBC 不知道 SQL 语句期望的类型。因此它在没有任何转换的情况下传递了很长时间的参数,并依赖于数据库来正确处理参数。

有人可能会争辩说,如果注册了匹配的转换器,它应该转换参数,但目前情况并非如此。

因此目前的解决方案是自己转换参数并将参数类型更改为 java.util.Date 或您的 JDBC 驱动程序接受的任何类型。

对于那些来这里寻找解决方案以生成精度优于毫秒的 java.sql.Timestamp 实例的人(不推荐接受 nanos 的 Timestamp 构造函数):

Timestamp timestamp = Timestamp.from(Instant.now());

这假设您的操作系统支持高于毫秒的系统时钟精度。它对于支持优于毫秒 TIMESTAMP 精度的数据库很有用,例如支持微秒级精度的 PostgreSQL。

您可以将其转换回 InstantLocalDateTime:

System.out.println(timestamp.toInstant()); // UTC

System.out.println(timestamp.toLocalDateTime()); // local time

我还将重申 stoetti 在评论中提供的信息,根据 stoetti 提供的文档 link, https://jdbc.postgresql.org/documentation/head/8-date-time.html,PostgreSQL JDBC 驱动程序确实将以下 java.time 类 识别为时间戳:

java.time.LocalTime 作为 TIME [ WITHOUT TIMEZONE ]

java.time.LocalDateTime 作为 TIMESTAMP [ WITHOUT TIMEZONE ]

java.time.OffsetDateTime 作为 TIMESTAMP WITH TIMEZONE

但不是 java.time.Instant,正如 stoetti 指出的那样。