使用 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。
您可以将其转换回 Instant
或 LocalDateTime
:
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 指出的那样。
我试图在我的存储库中编写一个类似于此的查询方法
@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。
您可以将其转换回 Instant
或 LocalDateTime
:
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 指出的那样。