Java 将LocalDateTime持久化到DB2时间戳列中

Java 将LocalDateTime持久化到DB2时间戳列中,java,jdbc,db2,Java,Jdbc,Db2,我一直在尝试将LocalDateTime持久化到DB2 10.5中的时间戳列中,但失败了,错误如下: [jcc][1091][10824][4.26.14]无效的数据转换:参数实例2020-01-02T12:34:56对于请求的转换无效。ERRORCODE=-4461,SQLSTATE=42815 我正在使用IBMJDBC驱动程序:“JDBC驱动程序IBMDataServerDriverforJDBC和SQLJ4.26.14”,它实现了JDBC规范4.1 表定义为: create table t

我一直在尝试将LocalDateTime持久化到DB2 10.5中的时间戳列中,但失败了,错误如下:

[jcc][1091][10824][4.26.14]无效的数据转换:参数实例2020-01-02T12:34:56对于请求的转换无效。ERRORCODE=-4461,SQLSTATE=42815

我正在使用IBMJDBC驱动程序:“JDBC驱动程序IBMDataServerDriverforJDBC和SQLJ4.26.14”,它实现了JDBC规范4.1

表定义为:

create table t1 (
  id int,
  a timestamp
);
Java代码是:

LocalDateTime dt = LocalDateTime.of(2020, 1, 2, 12, 34, 56);
PreparedStatement ps = conn.prepareStatement(
  "insert into t1 (id, a) values (?, ?)"
);
int id = 1;
ps.setInt(1, id);
ps.setObject(2, dt); // fails here
ps.execute();
我可以看到它甚至没有到达
ps.execute()
方法。我已经读到JDBC 4.2驱动程序可能会解决这个问题,但我在任何地方都找不到它。

使用以下方法更改要使用的代码:

如果
dt
可以为空,则使用三元运算符:

ps.setTimestamp(2, (dt == null ? null : Timestamp.valueOf(dt)));
根据主题,您应该使用
java.sql.Timestamp
处理
Timestamp
表列

表1。Java数据类型到数据库服务器数据类型的映射,用于更新数据库表

Java data type      Database data type
------------------  ------------------
...
java.sql.Timestamp  TIMESTAMP, ...

是否将LocalDateTime转换为java.sql.Timestamp?这有帮助吗听起来这个驱动程序不符合JDBC4.2,向IBM要一个符合JDBC4.2的驱动程序。好的,我想我可以这样做。但这很奇怪。
TIMESTAMP
(本地时间)与
java.sql.TIMESTAMP
(世界时间)遵循不同的时间线。没有直接转换,因为时间偏移/区域必须参与转换。JDBC 4.2增加了对将
java.time.LocalDateTime
映射到
时间戳
列的支持(参见JDBC 4.2规范,第3.1节更改概述)@MarkrotVeel我仍然认为数据库
时间戳
和带有时区的
时间戳
是完全不同的数据类型。我觉得数据不应该在没有适当的显式转换的情况下从一个流向另一个,永远不应该进行无缝/自动/隐藏转换。也许应该有两种不同的JDBC方法;类似于:
ps.setTimestamp()
ps.setTimestamp()
或类似的东西,但这只是我的问题。@jdbc4.2中已经出现了类似的情况。带时区的
时间戳
映射到
java.TIME.OffsetDateTime
,而不是
java.TIME.LocalDateTime
(该时间戳映射到
时间戳(不带时区)
)。那些
java.time
类型都是使用
setObject
设置的,并使用
getObject
检索的。JDBC专家组决定不再有新类型的显式设置器。我认为将
LocalDateTime
(本地时间)转换为
时间戳
(世界时间)从根本上是错误的。不过,我仍然没有看到更好的解决方法。“既然JDBC驱动程序不支持<代码> LoalDATECTIMECT/<代码>,那么唯一的方法是<代码>时间戳<代码>或代码>字符串< /代码>,我强烈反对使用<代码>字符串< /代码>,这意味着唯一的方法是使用<代码>时间戳< />代码>,所以不管你是否考虑过它。“根本错误”与否,你别无选择。--好吧,除非你能找到一个支持
LocalDateTime
的JDBC驱动程序的更新版本。我同意。看来JDBC规范在20年(1997年)里忽略了
TIMESTAMP
TIMESTAMP WITH TIME ZONE
之间的区别因为它只有一个
setTimestamp()
方法来处理两种[完全不同的]数据类型。而且,Java 8可能错过了解决这个问题的良机+1@TheImpaler不,JDBC总是(Java 1.2+)支持带有时区的
时间戳
,方法中的时区在
日历
对象中指定。目前只有Db2 for Z/OS平台支持带有时区的
时间戳
本机作为列数据类型,但在Db2 for Linux Unix Windows或i系列的发布版本中尚不可用。此外,如果您想保留时区详细信息,jdbc应用程序必须使用
com.ibm.db2.jcc.DBTimestamp
对象。但是您的问题指定了DB2V10.5,它是LUW版本。
Java data type      Database data type
------------------  ------------------
...
java.sql.Timestamp  TIMESTAMP, ...