web-dev-qa-db-fra.com

hibernate 4 et joda-time

sont-ils heureux en mariage?

J'utilise la dernière version de hibernate (4) et la version 1.3 de joda-time hibernate support , que je crois également être la dernière version actuelle.

Tout semble fonctionner correctement (les colonnes de date ont été créées comme prévu) lors de l'utilisation des annotations:

@Column
@Type(type="org.joda.time.contrib.hibernate.PersistentLocalDate")
private LocalDate myDate; 

Y a-t-il des problèmes connus avec l'utilisation de ces versions ensemble?

Mise à jour Il s'avère que les colonnes sont créées mais incapables de remplir des données:

Le traitement du gestionnaire a échoué; l'exception imbriquée est Java.lang.AbstractMethodError: org.joda.time.contrib.hibernate.PersistentLocalDateTime.nullSafeSet

Ils sont incompatibles, et je devrais utiliser type d'utilisateur . Voir la réponse ci-dessous.

62
NimChimpsky

Un manque de documentation distinct, signifie qu'il pourrait être utile pour moi d'écrire les étapes requises pour l'intégration. Assurez-vous que vos bibliothèques sont à jour.

Vous aurez besoin de: [en supposant que vous avez déjà hibernate4]

Dernière version de joda-time

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.0</version>
</dependency>

et type d'utilisateur lib

<dependency>
    <groupId>org.jadira.usertype</groupId>
    <artifactId>usertype.core</artifactId>
    <version>3.0.0.CR1</version>
</dependency>

Ensuite, utilisez les éléments suivants dans les classes d'entité (ne doit pas nécessairement être LocalDateTime, peut être l'une des classes persistantes disponibles):

import org.joda.time.LocalDateTime;

et pour la définition des colonnes:

@Column(name="updated", nullable = false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime updated;
96
NimChimpsky

J'ajouterai cela comme une réponse distincte car il s'agit à mon avis d'informations importantes pour quiconque passe à Hibernate 4 et a besoin de migrer vers les types temporels persistants de jadira. Cette page est très bien classée dans les résultats de recherche Google pour hibernate 4 et jodatime, je vais donc l'ajouter ici. (Pour une discussion séparée de ce problème, voir: Joda time DateTime stocke incorrectement dans la base de données )

Si vous êtes dans un fuseau horaire autre que UTC, une pièce de configuration importante est nécessaire afin d'obtenir le même comportement que vous le feriez avec un type de support hibernate joda-time. Le mode de fonctionnement par défaut des types temporels de jadira consiste à convertir toutes les valeurs dans le fuseau horaire UTC avant de persister dans la base de données et à les reconvertir dans le fuseau horaire du système lors du chargement des valeurs à partir de la base de données.

J'ai été brûlé par cela après la mise à niveau, quand j'avais beaucoup d'horodatages avec mon fuseau horaire exact dans la base de données (UTC + 1 (+2 en été)). Lors du chargement après la mise à niveau vers Hibernate 4, 1 ou 2 heures (selon que l'horodatage était ou non pendant l'heure d'été) a été ajoutée à la valeur dans la base de données, ce qui signifie que tous les horodatages existants ont été présentés par erreur. De plus, de nouvelles valeurs d'horodatage ont été stockées dans la base de données avec le fuseau horaire UTC, ce qui les a conduites à apparaître correctement dans l'application, mais incorrectes dans la base de données. Dans l'ensemble, un désordre chaud de fuseaux horaires et d'horodatages.

Donc, afin d'obtenir le même comportement qu'avec joda-times hibernate-support (le datetime étant persisté étant du fuseau horaire du serveur en question, et les horodatages dans la base de données étant les mêmes que ceux qui sont chargés dans l'application) , les propriétés suivantes doivent être ajoutées à la configuration JPA/Hibernate (dans mon cas, hibernate.properties):

jadira.usertype.autoRegisterUserTypes=true
jadira.usertype.databaseZone=jvm
jadira.usertype.javaZone=jvm

Cela garantira que les horodatages dans la base de données seront du même fuseau horaire que celui de l'application, qui à son tour sera le fuseau horaire du jvm (dans la plupart des cas, l'horloge du serveur d'applications).

De plus, d'après ce que je comprends, la propriété autoRegisterUserTypes- supprime le besoin de @Type- annotation pour une sélection de types communs, parmi lesquels les types Jodatime DateTime et LocalDate.

29
Tobb