Ada*_*dam 5 timezone hibernate jpa
我正在尝试使用定义将数据添加到oracle 11g数据库中的表.
CREATE TABLE FOO_TIME_TEST
(ID NUMBER(20) NOT NULL, TIME TIMESTAMP(6),
CONSTRAINT FOO_TIME_TEST_PK PRIMARY KEY (ID) USING INDEX);
CREATE UNIQUE INDEX "foo_time_test_idx" ON "FOO_TIME_TEST" (TIME)
Run Code Online (Sandbox Code Playgroud)
使用Joda时间的Hibernate/JPA映射具有以下内容
@Type(type = "com.foo.PersistentDateTime")
@Column(name = "TIME")
public DateTime getTime() {
return time;
}
Run Code Online (Sandbox Code Playgroud)
映射类PersistentDateTime相关位
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws SQLException {
if (value == null) {
Hibernate.TIMESTAMP.nullSafeSet(preparedStatement, null, index);
} else {
Hibernate.TIMESTAMP.nullSafeSet(preparedStatement, ((DateTime) value).toDate(), index);
}
}
public int[] sqlTypes() {
return new int[] { Types.TIMESTAMP, };
}
Run Code Online (Sandbox Code Playgroud)
并且要编写的代码是这样的,它是在使用plusTime()的循环中,但我将它隔离到这两个调用.
{
DateTime time = new DateTime(2012, 10, 28, 0, 0, DateTimeZone.UTC);
FooTest data = new FooTest();
data.setTime(time);
em.persist(data);
System.out.println(time + " " + time.getMillis() / 1000 / 60 / 60);
}
{
DateTime time = new DateTime(2012, 10, 28, 1, 0, DateTimeZone.UTC);
FooTest data = new FooTest();
data.setTime(time);
em.persist(data);
System.out.println(time + " " + time.getMillis() / 1000 / 60 / 60);
}
Run Code Online (Sandbox Code Playgroud)
产量
2012-10-28T00:00:00.000Z 375384
2012-10-28T01:00:00.000Z 375385
19:23:42,081 WARN JDBCExceptionReporter:100 - SQL Error: 1, SQLState: 23000
19:23:42,081 ERROR JDBCExceptionReporter:101 - ORA-00001: unique constraint (Foo.foo_time_test_idx) violated
Run Code Online (Sandbox Code Playgroud)
我已经尝试删除唯一索引,然后代码成功但数据库中的两行是相同的:
ID Time
1 28-OCT-12 01.00.00.000000000 AM
2 28-OCT-12 01.00.00.000000000 AM
Run Code Online (Sandbox Code Playgroud)
启用休眠跟踪后,它似乎显示两个不同的日期被展平为相同的值.
Hibernate: insert into FOO_TIME_TEST (ID, TIME) values (?, ?)
07:38:54,217 TRACE TimestampType:151 - binding '2012-10-28 01:00:00' to parameter: 22
Hibernate: insert into FOO_TIME_TEST (ID, TIME) values (?, ?)
07:38:54,217 TRACE TimestampType:151 - binding '2012-10-28 01:00:00' to parameter: 22
Run Code Online (Sandbox Code Playgroud)
真的需要ojdbc-6.jar的源代码来进一步调试......
我通过下载适用于11.2.0.2.0的ojdbc6_g.jar并将classpath与-Doracle.jdbc.Trace = true选项一起放入此处以及自定义java util log.properties来启用更多调试
这在每次绑定调用之后提供附加信息,在两种情况下都显示01:00值.
Nov 2, 2012 8:20:21 AM oracle.jdbc.driver.OraclePreparedStatementWrapper setTimestamp
TRACE_30: 3C322E7D Enter: 22, 2012-10-28 01:00:00.0
Nov 2, 2012 8:20:21 AM oracle.jdbc.driver.OraclePreparedStatement setTimestamp
FINE: 3C322E7D Public Enter: 22, 2012-10-28 01:00:00.0
Nov 2, 2012 8:20:21 AM oracle.jdbc.driver.OraclePreparedStatement setTimestampInternal
FINER: 3C322E7D Enter: 22, 2012-10-28 01:00:00.0
Run Code Online (Sandbox Code Playgroud)
当您使用时区存储时间时,我建议使用 TIMESTAMP(3) WITH TIME ZONE 类型。
CREATE TABLE TIME_TABLE
(
YOUR_TIME TIMESTAMP(3) WITH TIME ZONE,
TIME_ZONE VARCHAR (64 BYTE),
)
Run Code Online (Sandbox Code Playgroud)
对于 hibernate 映射,请使用 Joda 类 org.joda.time.contrib.hibernate.PersistentDateTimeTZ,下面是 XML 映射片段。
<property name="yourTime" type="org.joda.time.contrib.hibernate.PersistentDateTimeTZ">
<column name="YOUR_TIME" />
<column name="TIME_ZONE" />
</property>
Run Code Online (Sandbox Code Playgroud)
我不熟悉基于注释的 Hibernate 映射,但我认为它看起来像这样(我还没有尝试过):
@Type(type = "org.joda.time.contrib.hibernate.PersistentDateTimeTZ")
@Columns(columns = { @Column(name = "YOUR_TIME"), @Column(name = "TIME_ZONE") })
public DateTime getYourTime() {
return yourTime;
}
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助。
PS 我不认识您正在使用的 Joda DateTime 构造函数:它似乎没有秒和毫秒参数。