3

UTCタイムゾーンを使用して必要な日付を作成する方法を見つけました: Java日付と夏時間

したがって、「Sun Mar 25 02:00:00」を作成できますが、この日付をHibernateに挿入すると、書き込まれません。hibernateは、上書きできない別のタイムゾーンを使用しているようです。

私の問題は、UTCタイムゾーンを使用している場合でも、この日付「Sun Mar2502:00:00」をHibernate/H2データベースに挿入できないことです。

更新1:これらの値を挿入しようとしています:

Sun Mar 25 01:00:00 UTC 2012
Sun Mar 25 02:00:00 UTC 2012
Sun Mar 25 03:00:00 UTC 2012
Sun Mar 25 04:00:00 UTC 2012
Sun Mar 25 05:00:00 UTC 2012
Sun Mar 25 06:00:00 UTC 2012
Sun Mar 25 07:00:00 UTC 2012
Sun Mar 25 08:00:00 UTC 2012
Sun Mar 25 09:00:00 UTC 2012
Sun Mar 25 10:00:00 UTC 2012
Sun Mar 25 11:00:00 UTC 2012
Sun Mar 25 12:00:00 UTC 2012
Sun Mar 25 13:00:00 UTC 2012
Sun Mar 25 14:00:00 UTC 2012
Sun Mar 25 15:00:00 UTC 2012
Sun Mar 25 16:00:00 UTC 2012
Sun Mar 25 17:00:00 UTC 2012
Sun Mar 25 18:00:00 UTC 2012
Sun Mar 25 19:00:00 UTC 2012
Sun Mar 25 20:00:00 UTC 2012
Sun Mar 25 21:00:00 UTC 2012
Sun Mar 25 22:00:00 UTC 2012
Sun Mar 25 23:00:00 UTC 2012

しかし、データベースには次のものがあります。

データベース内

4

3 に答える 3

1

これはJDBCの「機能」であり、Hibernateの機能ではありません。したがって、この動作は、Hibernateオプションではなく、jdbcオプション(hibernate.cfg.xmlのjdbc接続文字列)で変更できます。デフォルトでは、日付値は常にクライアントアプリケーションのタイムゾーンに保存されます(より論理的であると思われるため、データベースのタイムゾーンには保存されません)。たとえば、MySQLは、データベースに日付値を常にUTCで保存するように強制するjdbc接続オプションを認識しています。H2がそのようなオプションを知っているかどうかはわかりませんが、そうではないかもしれません。

あなたの例では、3月25日が夏時間の最初の日でした。3月25日02:00がタイムゾーンに存在しなかったため、データベースに見つかりません。

接続文字列にオプションが必要ない場合(すべてのデータベースで使用できるとは限らないという欠点があります)、問題を回避する方法は3つあります。

  1. 挿入する前と読んだ後、プログラムでタイムゾーンの会話を行います。これに加えて、通常のgetter get / setMyTime()に加えて、Hibernate get / setHibernateMyTime()専用の追加のgetterとsetterを記述します。ここで、タイムゾーン変換を行い、マッピングファイルまたは注釈で使用します。タイムゾーンの変換には、TimeZone.getOffset()を使用できます。

  2. 日付の代わりに文字列を使用します。この場合、タイムゾーン変換を行う必要はありませんが、文字列を日付に、またはその逆に変換する必要があります。

  3. UTCを現地時間としてアプリケーションを実行します。これには、ユーザーインターフェイスなど、どこかでユーザーの現地時間が必要な場合に不利な点があります。

アプリケーションでソリューション1を実行しました。

于 2013-01-08T07:45:59.687 に答える
0

Johannaが述べたように、このタイムゾーンシフトの問題を処理する方法にはいくつかのオプションがあります。より詳細な方法で問題を説明し、より多くの例と解決策を提供する記事もあります。

前の回答のオプション番号1が考慮され、すべてのコードを自分で記述したくない場合は、小さなオープンソースライブラリを使用できますDbAssist java.util.Datejava.util.Timestampをカスタムにマップします。カスタムUtcDateTypeは、データベースの読み取りまたは書き込みのたびに、DB内の日付をUTCタイムゾーンで処理するように、セッターとゲッターを内部的にオーバーライドします。エンティティクラスをまったく変更しないので、これは便利なソリューションです。

依存関係を追加するだけです(5.2.2をHibernateバージョンに置き換えます)。

<dependency>
    <groupId>com.montrosesoftware</groupId>
    <artifactId>DbAssist-5.2.2</artifactId>
    <version>1.0-RELEASE</version>
</dependency>

次に、プロジェクトのgithubのインストールガイドで説明されているように修正を適用します。エンティティフィールドのマッピングにJPAアノテーションとHBMファイルのどちらを使用するかによって異なるため、ここではコピーしません。ただし、これは単純なワンライナーのセットアップです。

于 2016-11-15T15:09:07.543 に答える
0

テーブルのデータ構造を説明できますか?その列にDATETIMEまたはTIMESTAMPを使用していますか?

MySQLの公式ドキュメントによると、MySQLはTIMESTAMP値を現在のタイムゾーンからUTCに変換して保存し、UTCから現在のタイムゾーンに変換して取得します。この変換には、JDBC接続の現在のタイムゾーンが使用されます。

この動作は奇妙ですが正しいです。「SunMar2502:00:00」はタイムゾーン(おそらくセンターヨーロピアン)に存在しません。その日付を保存する必要がある場合は、DATETIMEとして列を作成できます。

于 2016-11-24T20:14:54.293 に答える