java.time.LocalDateTime
Hibernate と JPA を使用して永続化しようとしています。Jadira フレームワーク ("org.jadira.usertype:usertype.core:3.2.0.GA" & "org.jadira.usertype:usertype.extended:3.2.0.GA") を使用しました。package-info.java
ファイルを作成し、@TypeDefs({@TypeDef(defaultForType = java.time.LocalDateTime.class, typeClass = org.jadira.usertype.dateandtime.threeten.PersistentLocalDateTime.class)})
そこに作成しました。ソリューションをテストしたところ、java.time.LocalDateTime
フィールドは MySQL データベースのDATETIME
列 (ほぼ) に正しく格納/取得されました。
唯一の問題は、データベースの値が Java のフィールドからの正しい時間値に対して +2 時間であることです。私はCEST(UTC + 2)にいるので、これはタイムゾーンの問題であることを理解しました. のコードをデバッグしたPersistentLocalDateTime
ところ、これが見つかりました。
PersistentLocalDateTime
使っているorg.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper
AbstractTimestampThreeTenColumnMapper
フィールドZoneOffset databaseZone
はデフォルトでZoneOffset.of("Z")
(UTC) に設定されています。- 私のデータベースは UTC タイムゾーンである (そしてアプリケーションは UTC+2 である) と考えているため、データベースへの変換中に 2 時間が追加されます (データベースからの変換中に私の時間から 2 時間が減算されます)。したがって、アプリケーションでは正しい日付と時刻が表示されますが、データベースでは表示されません。
にパラメーターを追加できることがわかった@TypeDef
ので、以下のように指定しました。
@TypeDef(defaultForType = LocalDateTime.class, typeClass = PersistentLocalDateTime.class,
parameters = {
@Parameter(name = "databaseZone", value = "+02:00")
}),
しかし、私には例外があります:
java.lang.IllegalStateException: Could not map Zone +02:00 to Calendar
at org.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper.getHibernateType(AbstractTimestampThreeTenColumnMapper.java:59)
もう少しデバッグしました。AbstractTimestampThreeTenColumnMapper
次の 2 つの方法があります。
public final DstSafeTimestampType getHibernateType() {
if (databaseZone == null) {
return DstSafeTimestampType.INSTANCE;
}
Calendar cal = resolveCalendar(databaseZone);
if (cal == null) {
throw new IllegalStateException("Could not map Zone " + databaseZone + " to Calendar");
}
return new DstSafeTimestampType(cal);
}
private Calendar resolveCalendar(ZoneOffset databaseZone) {
String id = databaseZone.getId();
if (Arrays.binarySearch(TimeZone.getAvailableIDs(), id) != -1) {
return Calendar.getInstance(TimeZone.getTimeZone(id));
} else {
return null;
}
}
getHibernateType
resolveCalendar
メソッドが を返すため、メソッドは例外をスローしますnull
。なぜそれが返されるのnull
ですか?とのタイムゾーン ID が一致しないためjava.time.ZoneOffset
ですjava.util.TimeZone
。私が見る限り、一致する唯一の可能な値はZ
. その他の値を指定すると、例外が発生します。
これを正しく設定する方法はありますか?それとも Jadira フレームワークのバグですか?