4

java.time.LocalDateTimeHibernate と 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ところ、これが見つかりました。

  1. PersistentLocalDateTime使っているorg.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper
  2. AbstractTimestampThreeTenColumnMapperフィールドZoneOffset databaseZoneはデフォルトでZoneOffset.of("Z")(UTC) に設定されています。
  3. 私のデータベースは 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;
    }
}

getHibernateTyperesolveCalendarメソッドが を返すため、メソッドは例外をスローしますnull。なぜそれが返されるのnullですか?とのタイムゾーン ID が一致しないためjava.time.ZoneOffsetですjava.util.TimeZone。私が見る限り、一致する唯一の可能な値はZ. その他の値を指定すると、例外が発生します。

これを正しく設定する方法はありますか?それとも Jadira フレームワークのバグですか?

4

1 に答える 1