2014-09-22 88 views
0

使用休眠選擇時間戳字段獲取錯誤時間。使用休眠選擇時間戳字段獲取錯誤時間選擇


我們使用Hibernate框架和Postgres數據庫。

我們有一張表,它在數據類型TIMESTAMP WITH TIME ZONE的列中存儲'created_time'。

+------------------------------------------+ 
+ created_time + 
+------------------------------------------+ 
+ 2014-09-22 04:30:00.756 + 
+ -----------------------------------------+ 

假設我們有一個數據'2014年9月22日04:30:00.756' 在 'CREATED_TIME'

我用下面的Hibernate查詢

query= "SELECT column1,column2,createdTime FROM TableName"; 
… 
… 
List<Object[]> dataList=selectQuery.list(); 
for(Object data[] : dataList) 
{ 
System.out.println("Date and time -> "+data[2].toString()); //Time coming wrong here 
} 

當我去throught在DataList我發現日期是正確的到來,但時間是別的東西像'11:45:00.345'

如果我在pgAdminIII中使用了相同的查詢,則表示它正確地進入。

但隨着休眠它錯了。

我甚至試過SQL查詢。我仍然面對錯誤的時間問題。

我沒有得到解決方案,當我搜索網絡。

回答

1

可能你正在獲取本地時區而不是服務器時區。 因此,要獲得服務器的時間戳,因爲它是改變你的查詢類似下面:

query= "SELECT column1,column2,createdTime at time zone current_setting('TIMEZONE') FROM TableName"; 
+1

正確。 Postgres將日期時間值轉換並存儲到UTC。默認情況下,檢索時會應用當前的默認時區,並將調整後的值返回給客戶端(pgAdmin)。由於時區信息未被存儲,'TIMESTAMP WITH TIME ZONE'是一個誤用。更好的名字應該是'TIMESTAMP WITH RESPECT FOR TIME ZONE'。因此,對於檢索指定您想要的時區,是UTC或本地[時區名稱](http://en.wikipedia.org/wiki/List_of_tz_database_time_zones)。 – 2014-09-22 17:33:00

1

這是一個常見的問題,當我們要讀取從DB /寫日期並將其存儲在UTC時區。例如,如果使用Hibernate從DB讀取日期爲9:54的日期,由於JDBC,我們得到一個9:54時間,但解釋爲本地日期;對我來說,這將是9:54 UTC+2。這意味着在Java方面,我們只獲得了7:54 UTC時間。這個問題在這個article有更好的解釋。

無論如何,你可以通過使用一個小的DbAssist開源庫輕鬆修復它。它將標準Date字段映射到自定義UtcDateType,這迫使Hibernate將日期視爲UTC。您可以在項目的github wiki上找到有關支持的Hibernate版本和安裝指南的更多詳細信息。

如果你正在使用JPA註解來映射實體,只需添加以下依賴:

<dependency> 
    <groupId>com.montrosesoftware</groupId> 
    <artifactId>DbAssist-5.2.2</artifactId> 
    <version>1.0-RELEASE</version> 
</dependency> 

應用的解決方法是非常簡單的;例如,如果你正在使用persistence.xml文件,你的Hibernate,只需添加一行裏面persistence-unit標籤:

<class>com.montrosesoftware.dbassist.types</class> 

對於其他的Hibernate配置,e.g與Spring啓動,請參閱GitHub的項目頁面。無論如何,修復程序在此步驟後立即生效,現在通過Hibernate讀取(並保存到)數據庫的所有日期都被視爲UTC。