web-dev-qa-db-ja.com

現在のタイムゾーンのHibernateクエリに日付パラメーターを割り当てる方法

名前付きSQLパラメーターに日付を割り当てると、Hibernateは自動的にそれをGMT時間に変換します。どのようにしてすべての日付で現在のサーバーのタイムゾーンを使用しますか?

クエリがあるとしましょう:

Query q = session.createQuery("from Table where date_field < :now");
q.setDate("now", new Java.util.Date());

「現在」はGMT時間に設定され、「新しい日付()」は現在のサーバー時間を取得します。

ありがとう。

33
serg

Hibernateは日付をGMTに自動的に変換しないことが判明したため、query.setDate()を使用すると時刻が切り捨てられるため、「2009-01-16 12:13:14」を渡すと「2009 -01-16 00:00:00」。

時間を考慮するには、代わりにquery.setTimestamp("date", dateObj)を使用する必要があります。

65
serg

timeZone同期値が必要な場合は、HQLでnow()を使用できます。また、Jodaライブラリを使用することをお勧めします。 hibernate-pluginモジュールがあります。

2
Maksim

Hibernateはタイムゾーンを認識しません。クエリを実行する前に、タイムゾーン変換を行う必要があります。

たとえば、データベースサーバーがCSTに設定されているが、ユーザーがESTにいる場合、クエリへの入力であるタイムスタンプに1時間を追加する必要があります。

2
Clay

カスタムのHibernate日付型を使用します。クエリにパラメーターを設定するときはいつでも、ベースクラスまたはユーティリティメソッドを使用して、ユーザーのタイムゾーンをカスタムタイプパラメーターに渡すことができます。

クエリのユーティリティメソッドで時間を手動で調整するだけで対応できますが、この方法では、データベースで読み書きされる日付も正しく変換されます。このメソッドは、データベースがローカルタイムゾーンで日付を保存する状況も処理します。したがって、あるタイムゾーンにユーザーがいて、別のタイムゾーンにデータベースサーバーがあり、GMTを使用してJavaである場合でも、すべてを正しく取得できます。最終的には次のようになります。

Properties properties = new Properties();
properties.setProperty("timeZone", databaseTimeZone);
query.setParameter("from", dateEnteredByUser, Hibernate.custom(LocalizedDateType.class, properties));

追加のボーナスとして、これを使用して、SQL Serverが23:59:59.999を翌日に変換するという事実に対処します。カスタムタイプでは、そのことを確認してバックオフします。

2
Brian Deterling

HibernateチームはsetTimestamp(String name、Date val)メソッドとorg.hibernate.Queryバージョン以降のインターフェース5.2

 /* @deprecated (since 5.2) use {@link #setParameter(int, Object)} or
    {@link #setParameter(int, Object, Type)}  instead
 */

以下のコードを使用できます:

import org.hibernate.query.Query;
...
Query query = session.createQuery("from Table where date_field < :now");
query.setParameter("now", new Date(), TimestampType.INSTANCE );

setDate時間部分を削減するメソッドも非推奨であり、このオプションに置き換えることができます(同じインターフェースから) org.hibernate.query.Query):

query.setParameter("firstMomentOfToday", new Date(), DateType.INSTANCE);

Java 8およびOracle 'ojdbc8.jar'などの関連するjdbcドライバーおよびサポートされている休止状態バージョンで使用する場合、これは期待どおりに動作しない可能性があります。代わりに新しいJava.time.LocalDateとLocalDateTimeを使用するのが賢明です。

1
Kayvan Tehrani