2012-11-13 6 views
21

Postgresql(9.0-801.jdbc3 JDBCドライバ)を使用するJPA 2アプリケーション(JPA実装としてHibernate 3.6を使用)があります。JPA 2エンティティのpostgresql "タイムスタンプ付きタイムスタンプ"のマッピング方法

「タイムゾーン付きタイムゾーン」フィールドを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.Datejava.util.Calendarを交換 - java.sql.Timestampを使用して何の違い
  • をしなかった - 私もうまくいきませんでしたカスタム@Type注釈(@Type(type="org.joda.time.contrib.hibernate.PersistentDateTimeTZ"))とorg.joda.time.DateTimeを使用してTimestamp
  • @Temporal注釈を適用することができないことを訴え

制約

  • このアプリケーションは、「レガシーシステム」と対話する - そう、日付フィールドの種類を変更することが

良いオプションではありません私の質問は:私は私の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がその一例です)。休止状態の場合、ジョーダタイムの拡張では、通常のタイムスタンプ+タイムゾーンのvarcharフィールドを使用してタイムゾーン対応のタイムスタンプを保存することができます(データベーススキーマの変更が制限されていたため、できませんでした)。 Jadira user typesまたは完全にカスタムのユーザータイプを使用してこの問題に対処することもできます。

このエンティティのユースケースは「読み取り専用」なので、私は一見、素朴な "解決策"を取り除くことができます。

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を使用してテーブル列を作成した場合、間接的にランタイム動作の詳細に影響を与えます。 –

関連する問題