2015-10-20 41 views
3

在我們的數據庫中,我們有多個具有日期字段的實體。 Oracle將每個日期看作相同的日期和時間部分。然而,JPA實體通過annotaton @Temporal區分。當我們想省略時間部分時,我們使用@Temporal(TemporalType.DATE)和Oracle對日期字段進行註釋,如果沒有,則保存00:00:00,我們只是不加註釋。@Temporal(TemporalType.DATE)與Oracle 12

例子:

@Entity 
public class MyEntity implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    private long myentityId; 

    @Temporal(TemporalType.DATE) 
    private Date importantDate; //01.01.2015 00:00:00 

    private Date creationDate; //01.01.2015 10:35:51 
    ... 
} 

... 
MyEntity me = new MyEntity(); 
me.setImportantDate(new Date()); 
me.setCreationDate(new Date()); 
... 

我們從甲骨文11升級到Oracle 12現在importantDate的時間部分不再省略!

我在兩個數據庫上使用完全相同的程序對此進行了廣泛的測試。 這實際上打破了我們的應用程序。

我能做些什麼來恢復以前的行爲?


更新1: 我將問題範圍縮小了下來:司機ojdbc6 12.1.0.1.0有問題,ojdbc6 11.2.0.3.0按預期工作。 (都使用Oracle 12 DB)

這是11.1中修復的時間戳問題的延續嗎? (http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#08_01


更新2: 由於休眠似乎並不成爲問題,我寫用純JDBC一個例子:ojdbc6 11.1和ojdbc6之間切換時

OracleDataSource ods = new OracleDataSource(); 
... 
Connection conn = ods.getConnection(); 
PreparedStatement ps = conn.prepareStatement("UPDATE MyEntity SET importantDate = ? WHERE myentityId = 4385"); 
ps.setDate(1, new java.sql.Date(new java.util.Date().getTime())); 
ps.execute(); 
... 

該片段表現不同12.1。

+0

之後你有沒有在你的應用程序更新Oracle驅動程序呢? –

+1

您使用的是哪個版本的Hibernate?你在使用['Oracle12cDialect'](https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/dialect/Oracle12cDialect.html)嗎? – Tunaki

+0

我們仍然使用org.hibernate.dialect.Oracle10gDialect和OJDBC7驅動程序。現在嘗試新的方言。 – Thomas

回答

1

我們conntacted了Oracle支持,他們答覆如下(遺憾的是我不能提供鏈接到的答案,因爲需要一個Oracle支持賬戶):

新的行爲按預期正常運行

在JDBC 12.1.0.1中,getDate和setDate不會截斷日期的時間組件。此行爲與JDBC 11.2.0.X不同,時間組件被截斷。根據錯誤14389749,17228297,此更改是故意的,並且12c驅動程序的行爲是正確的。

爲我提供工作的解決方法:

解決方法1: 修改應用程序無法插入時間成分(例如用靜態UtilMethod)

public static Date truncateTime(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); }

解決方法#2: 從MOS下載並應用補丁19297927:(My Oracle Support)

  1. 單擊修補程序&更新選項卡。
  2. 輸入上面的補丁號並點擊搜索。
  3. 點擊補丁編號對應您的平臺從列表
  4. 點擊下載按鈕下載補丁。
  5. 下載前閱讀所有適用的註釋,然後點擊下載按鈕。

修補在%Oracle_Home%\oracle_common\modules\oracle.jdbc_12.1.0更換ojdb7.jar並添加-Doracle.jdbc.DateZeroTime=true到您的JVM參數

+0

感謝您的詳細信息。當Oracle支持告訴我們,行爲如預期的那樣,Apache的Hibernate團隊沒有迴應,我們實施了觸發器的解決方法以備將來保存。 – Thomas