2012-11-13 144 views
21

我有一個使用Postgresql(具有9.0-801.jdbc3 JDBC驅動程序)的JPA 2應用程序(使用Hibernate 3.6作爲JPA實現)。如何在JPA 2實體中映射postgresql「timestamp with time zone」

我在將「timestamp with time zone」字段映射到我的JPA實體時遇到問題。

下面是一個例子:

CREATE TABLE theme 
(
    id serial NOT NULL, 
    # Fields that are not material to the question have been edited out 
    run_from timestamp with time zone NOT NULL, 
    run_to timestamp with time zone NOT NULL, 
    CONSTRAINT theme_pkey PRIMARY KEY (id), 
    CONSTRAINT theme_name_key UNIQUE (name) 
) 

我試圖映射如下:

@Entity 
@Table(schema = "content", name = "theme") 
public class Theme extends AbstractBaseEntity { 
    private static final long serialVersionUID = 1L; 

    @Column(name = "run_from") 
    @NotNull 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date runFrom; 

    @Column(name = "run_to") 
    @NotNull 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date runTo; 

    /* The rest of the entity has been edited out */ 

我不斷獲取具有以下根本原因的異常:Caused by: org.hibernate.HibernateException: Wrong column type in public.backend_themetopic for column created. Found: timestamptz, expected: date

什麼我試過

  • java.util.Date更換java.util.Calendar - 由使用java.sql.Timestamp沒有區別
  • - 抱怨說我不能@Temporal標註適用於使用org.joda.time.DateTime與自定義@Type註解(@Type(type="org.joda.time.contrib.hibernate.PersistentDateTimeTZ"))一Timestamp
  • 也沒有工作

限制條件

  • 該應用程序與「遺留系統」互動 - 因此,改變類型的日期字段是不是一個好的選擇

我的問題是:我應該如何映射這些時區意識到時間戳到我的JPA實體?

回答

6

我最終通過關閉模式驗證來做出這個「工作」 - 以一種駭人聽聞的方式。

以前,我在我的persistence.xml中有<property name="hibernate.hbm2ddl.auto" value="validate"/>"hibernate.hbm2ddl.auto"。當我註釋掉這個屬性時,我的應用程序服務器啓動並且模型「工作」。

我的實體的最終形式是:

@Entity 
@Table(schema = "content", name = "theme") 
public class Theme extends AbstractBaseEntity { 
    private static final long serialVersionUID = 1L; 

    @Column(name = "run_from", columnDefinition = "timestamp with time zone not null") 
    @NotNull 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date runFrom; 

    @Column(name = "run_to", columnDefinition = "timestampt with time zone not null") 
    @NotNull 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date runTo; 

    /* Getters, setters, .hashCode(), .equals() etc omitted */ 

閱讀這個頗有幾分後,我得到的印象是,有沒有簡單的方法來映射PostgreSQL的時間戳和時區列。

某些JPA實現+數據庫組合本身支持此(EclipseLink + Oracle是一個示例)。對於使用jodatime擴展的休眠模式,可以使用時區的正常時間戳+ varchar字段來存儲時區感知時間戳(由於受限於更改數據庫模式,我無法這樣做)。或者完全自定義的用戶類型也可以用來解決這個問題。

我需要注意的是,我的這個實體的用例是「只讀」,所以我可以逃避一個看似天真的「解決方案」。

5

添加@Column(columnDefinition= "TIMESTAMP WITH TIME ZONE")

@Column(name = "run_from", columnDefinition= "TIMESTAMP WITH TIME ZONE") 
@NotNull 
@Temporal(TemporalType.TIMESTAMP) 
private Date runFrom; 
+0

這是隻對DDL自動或運行過程中實際有用的事情? – cslotty

+0

'columnDefinition'值只用於DDL。但是,如果您的表列是使用該DDL創建的,則它也會間接影響運行時行爲的具體情況。 –

相關問題