35

Postgresql (9.0-801.jdbc3 JDBC ドライバー) を使用する JPA 2 アプリケーション (JPA 実装として Hibernate 3.6 を使用) があります。

「タイムゾーン付きタイムスタンプ」フィールドを 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.Calendarに置き換えるjava.util.Date- 違いはありません
  • using java.sql.Timestamp-@TemporalアノテーションをTimestamp
  • org.joda.time.DateTimeカスタム@Type注釈 ( ) での使用@Type(type="org.joda.time.contrib.hibernate.PersistentDateTimeTZ")も機能しませんでした

制約

  • このアプリケーションは「レガシー システム」と対話するため、日付フィールドのタイプを変更することは適切なオプションではありません

私の質問は、これらのタイムゾーン対応のタイムスタンプを JPA エンティティにどのようにマッピングすればよいですか?

4

2 に答える 2

12

私は最終的に、スキーマ検証をオフにすることで、この「機能」を(ハック的な方法で)作成しました。

以前は<property name="hibernate.hbm2ddl.auto" value="validate"/>"hibernate.hbm2ddl.auto"、persistence.xmlにありました。このプロパティをコメントアウトすると、アプリサーバーが起動し、モデルが「機能」しました。

私の実体の最終的な形は次のとおりです。

@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フィールドを使用してタイムゾーン対応のタイムスタンプを保存できます(データベーススキーマの変更が制限されていたため、これはできませんでした)。Jadiraユーザータイプまたは完全にカスタムのユーザータイプを使用して、この問題に取り組むこともできます。

このエンティティのユースケースは「読み取り専用」であることに注意する必要があります。そのため、一見ナイーブな「解決策」で逃げることができます。

于 2012-11-14T07:19:39.307 に答える
11

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

@Column(name = "run_from", columnDefinition= "TIMESTAMP WITH TIME ZONE")
@NotNull
@Temporal(TemporalType.TIMESTAMP)
private Date runFrom;
于 2015-07-11T18:25:37.983 に答える