2012-11-02 103 views
5

我想用定義將數據添加到Oracle 11g數據庫中的表中。帶時間戳和夏令時的休眠和oracle問題

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) 

使用約達時間與下列

@Type(type = "com.foo.PersistentDateTime") 
@Column(name = "TIME") 
public DateTime getTime() { 
    return time; 
} 

映射類中的休眠/ JPA映射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, }; 
} 

和寫入是這樣的,它是在代碼一個使用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); 
} 

輸出

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 

我試圖消除唯一索引,代碼將成功,但在數據庫中的兩行則是相同的:

ID Time 
1 28-OCT-12 01.00.00.000000000 AM 
2 28-OCT-12 01.00.00.000000000 AM 

與Hibernate跟蹤啓用後,它似乎顯示兩個不同的日期正被展平爲相同的值。

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 

真正需要的源ojdbc-6.jar可通過下載ojdbc6_g.jar的11.2.0.2.0並把在類路徑沿着進一步調試......

我已經啓用更多的調試所述-Doracle.jdbc.Trace = true選項的建議here和定製的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 
+0

如果它仍然是實際的:)請問您可以展示您的FooTime課程內容嗎?也許你已經解決了這個問題? –

回答

0

由於您正在存儲時區的時區,我建議使用類型TIMESTAMP(3)WITH TIME ZONE。

CREATE TABLE TIME_TABLE 
(
    YOUR_TIME TIMESTAMP(3) WITH TIME ZONE, 
    TIME_ZONE VARCHAR (64 BYTE), 
) 

對於hibernate映射使用約達類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> 

我不熟悉的基於註釋的Hibernate映射,但我相信它會是這個樣子(我還沒有嘗試過):

@Type(type = "org.joda.time.contrib.hibernate.PersistentDateTimeTZ") 
@Columns(columns = { @Column(name = "YOUR_TIME"), @Column(name = "TIME_ZONE") }) 
public DateTime getYourTime() { 
     return yourTime; 
} 

我希望這有助於。

P.S.我不認識你使用的Joda DateTime構造函數:它似乎沒有Seconds和Milliseconds參數。