web-dev-qa-db-fra.com

Comment attribuer des paramètres de date à la requête Hibernate pour le fuseau horaire actuel?

Lorsque vous attribuez une date à un paramètre SQL nommé, Hibernate le convertit automatiquement en heure GMT. Comment faites-vous utiliser le fuseau horaire actuel du serveur pour toutes les dates?

Disons que vous avez une requête:

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

"now" sera réglé sur l'heure GMT, tandis que "new Date ()" obtient l'heure actuelle de votre serveur.

Merci.

29
serg

Comme il s’est avéré que Hibernate ne convertit pas automatiquement les dates en heure GMT, il coupe simplement le temps si vous utilisez query.setDate(). Ainsi, si vous passez "2009-01-16 12:13:14", il devient "2009-01-16 00: 00:00 ". 

Pour prendre en compte le temps, vous devez utiliser plutôt query.setTimestamp("date", dateObj).

60
serg

Si vous avez besoin d'une valeur timeZone synchronized, vous pouvez utiliser now () dans votre HQL. Aussi, je vous suggère d'utiliser la bibliothèque Joda. Il a un module hibernate-plugin.

2
Maksim

Hibernate ignore les fuseaux horaires. Toute conversion de fuseau horaire doit être effectuée avant l'exécution de la requête. 

Par exemple, si votre serveur de base de données est défini sur CST, mais que l'utilisateur est sur EST, vous devrez ajouter 1 heure à tous les horodatages qui constituent l'entrée d'une requête. 

2
Clay

Nous utilisons un type de date Hibernate personnalisé. Chaque fois que nous définissons un paramètre sur une requête, nous utilisons une classe de base ou une méthode d'utilitaire afin de pouvoir passer le fuseau horaire de l'utilisateur dans le paramètre de type personnalisé. 

Vous pouvez vous contenter d'ajuster simplement l'heure dans la méthode de l'utilitaire pour les requêtes, mais de cette manière, les dates lues ou écrites dans la base de données sont également converties correctement. Cette méthode gère également la situation dans laquelle la base de données stocke la date dans son fuseau horaire local. Ainsi, même si vous avez un utilisateur dans un fuseau horaire, un serveur de base de données dans un autre et Java avec GMT, tout est clair. Il finit par ressembler à:

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

En prime, nous utilisons cela pour gérer le fait que SQL Server convertit le jour suivant en 23: 59: 59.999. Dans le type personnalisé, nous vérifions cela et le supprimons.

2
Brian Deterling

L'équipe Hibernate a déconseillé d'utiliser la méthodesetTimestamp (nom de la chaîne, date)ainsi que org.hibernate.Query interface depuis la version5.2:

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

Vous pouvez donc utiliser le code ci-dessous:

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

Il est à noter que la méthodesetDatequi réduit le temps d'arrêt est également obsolète et peut être remplacée par cette option (à partir de la même interface, org.hibernate.query.Query):

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