web-dev-qa-db-ja.com

休止状態4およびjoda-time

彼らは幸せに結婚していますか?

Hibernate(4)の最新バージョンと joda-time hibernate support のバージョン1.3を使用していますが、これも現在の最新リリースであると考えています。

注釈を使用する場合、すべてが正常に機能しているようです(日付列は期待どおりに作成されています):

@Column
@Type(type="org.joda.time.contrib.hibernate.PersistentLocalDate")
private LocalDate myDate; 

これらのバージョンを一緒に使用すると、既知の問題がありますか?

Updateカラムは作成されますが、データを取り込むことができません:

ハンドラー処理が失敗しました。ネストされた例外はJava.lang.AbstractMethodErrorです:org.joda.time.contrib.hibernate.PersistentLocalDateTime.nullSafeSet

これらは互換性がなく、 sertypeを使用する必要があります。以下の回答を参照してください。

62
NimChimpsky

明確なドキュメントの不足は、統合に必要な手順を書き留めておくと役立つことを意味します。ライブラリが最新であることを確認してください。

必要になります:[すでにhibernate4を持っていると仮定]

Joda-timeの最新バージョン

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.0</version>
</dependency>

およびusertype lib

<dependency>
    <groupId>org.jadira.usertype</groupId>
    <artifactId>usertype.core</artifactId>
    <version>3.0.0.CR1</version>
</dependency>

次に、エンティティクラスで次を使用します(LocalDateTimeである必要はなく、使用可能な永続化されたクラスのいずれかを使用できます)。

import org.joda.time.LocalDateTime;

列定義の場合:

@Column(name="updated", nullable = false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime updated;
96
NimChimpsky

私の意見では、Hibernate 4にアップグレードし、jadiraの永続的なテンポラルタイプの使用に移行する必要がある人にとって重要な情報であるため、これを別の回答として追加します。このページは、Hibernate 4およびjodatimeのGoogle検索結果で非常にランク付けされているため、ここに追加します。 (この問題の別の説明については、 Joda time DateTimeがデータベースに誤って保存する を参照してください)

UTC以外のタイムゾーンにいる場合、joda-time hibernate-supportタイプの場合と同じ動作を得るために、重要な設定が必要です。 jadiraの時間タイプのデフォルトの動作方法は、データベースに保持する前にすべての値をUTCタイムゾーンに変換し、データベースから値をロードするときにシステムのタイムゾーンに戻すことです。

アップグレード後、データベースに正確なタイムゾーンのタイムスタンプが多数あった場合(UTC + 1(サマータイムの場合は+2))に焼かれました。 Hibernate 4へのアップグレード後にロードすると、データベースの値に1または2時間(タイムスタンプが夏時間であったかどうかに応じて)が追加されたため、既存のすべてのタイムスタンプが誤って表示されました。さらに、新しいタイムスタンプ値はUTCタイムゾーンでデータベースに保存されたため、アプリケーションでは正しく表示されますが、データベースでは正しく表示されませんでした。全体として、タイムゾーンとタイムスタンプの大混乱。

そのため、joda-times hibernate-supportと同じ動作を得るために(永続化される日付時刻は問題のサーバーのタイムゾーンであり、データベースのタイムスタンプはアプリケーションにロードされているものと同じです) 、次のプロパティをJPA/Hibernate構成に追加する必要があります(私の場合、hibernate.properties):

jadira.usertype.autoRegisterUserTypes=true
jadira.usertype.databaseZone=jvm
jadira.usertype.javaZone=jvm

これにより、データベース内のタイムスタンプがアプリケーションのタイムゾーンと同じタイムゾーンになり、jvmのタイムゾーンになります(ほとんどの場合、アプリケーションサーバーのクロック)。

また、私が理解していることから、autoRegisterUserTypes- propertyは、Jodatime-types DateTimeおよびLocalDateなどの一般的なタイプの選択に対する@Type-アノテーションの必要性を取り除きます。

29
Tobb