Situation :
J'ai une classe persistante avec des variables de type java.util.Date :
import java.util.Date;
@Entity
@Table(name = "prd_period")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Period extends ManagedEntity implements Interval {
@Column(name = "startdate_", nullable = false)
private Date startDate;
}
Table correspondante dans la BD :
CREATE TABLE 'prd_period' (
'id_' bigint(20) NOT NULL AUTO_INCREMENT,
...
'startdate_' datetime NOT NULL
)
Ensuite, je sauvegarde mon objet Période dans la base de données :
Period p = new Period();
Date d = new Date();
p.setStartDate();
myDao.save(p);
Ensuite, si j'essaie d'extraire mon objet de la base de données, il est renvoyé avec la variable startDate de type Timestamp - et tous les endroits où j'essaie d'utiliser equals(...) renvoient false.
Pregunta : existe-t-il un moyen de forcer Hibernate à retourner les dates sous forme d'objets de type java.util.Date au lieu de Timestamp sans modification explicite de chacune de ces variables (par exemple, cela doit pouvoir fonctionner sans modification explicite des variables existantes de type java.util.Date) ?
NOTE :
J'ai trouvé un certain nombre de solutions explicites, où les annotations sont utilisées ou le setter est modifié - mais j'ai beaucoup de classes avec des variables de date - donc j'ai besoin d'une solution centralisée et tout ce qui est décrit ci-dessous n'est pas assez bon :
-
Utilisation de l'annotation @Type : - java.sql.Date sera retournée.
@Column @Type(type="date") private Date startDate;
-
Utilisation de l'annotation @Temporal(TemporalType.DATE) - java.sql.Date sera retournée.
@Temporal(TemporalType.DATE) @Column(name=”CREATION_DATE”) private Date startDate;
-
En modifiant le setter (copie profonde) - java.util.Date sera retourné
public void setStartDate(Date startDate) { if (startDate != null) { this.startDate = new Date(startDate.getTime()); } else { this.startDate = null; } }
-
Par la création de mon propre type : - java.util.Date sera retourné
Les détails sont donnés ici : http://blogs.sourceallies.com/2012/02/hibernate-date-vs-timestamp/
6 votes
Je pense que vous devriez utiliser une des réponses explicites que vous venez de montrer. Principalement pour la maintenance du code à l'avenir. Cela permettra à un nouveau développeur de voir exactement ce que vous faites, au lieu de passer beaucoup de temps à essayer de comprendre pourquoi les dates de votre système fonctionnent différemment de tous les autres systèmes hibernate existants.
0 votes
La deuxième solution me semble la meilleure. En outre, d'après votre article de blog, il semble que vous vous appuyez sur Hibernate pour créer la structure de votre base de données. Et si vous preniez les choses en main et utilisiez simplement
date
au lieu detimestamp
partout ?1 votes
+1 C'est un problème désagréable. Je travaille avec Hibernate depuis des années maintenant et je ne connais pas de cualquier documentation officielle d'Hibernate à ce sujet. J'utilise le setter modifié approche. Je fais aussi une copie profonde dans le getter car
java.util.Date
n'est pas immuable, donc une copie profonde devrait être préférée de toute façon.1 votes
Notez que l'approche setter ne fera rien si vous utilisez l'accès par champ plutôt que l'accès par propriété.
0 votes
Si le changement des classes Java est une option, la meilleure solution serait peut-être de se passer de
java.util.Date
et utiliser Joda-Time à la place. Il existe également une Projet de soutien à Hibernate ou le plus généralisé Projet de type utilisateur disponibles pour être utilisés avec Joda-Time.0 votes
@dim1902 Merci de partager votre type de date personnalisé. L'approche du setter ne fonctionnera pas non plus si vous utilisez un composant générique comme un
DataRange<T>
.0 votes
Quelle version d'Hibernate ?
0 votes
Ajout de
@Temporal(TemporalType.DATE)
annotation sur la variable date résolue par le problème.