OpenJPA conserve les champs des attributs de type java.sql.Date, java.sql.Time ou java.sql.Timestamp qui comportent une annotation javax.persistence.Temporal, alors qu'EclipseLink génère une exception.
Pour certaines combinaisons de l'annotation javax.persistence.Temporal et des attributs java.sql.Date, java.sql.Time et java.sql.Timestamp, vous devez ajouter un code convertisseur pour qu'EclipseLink soit compatible avec les tables créées par OpenJPA.
Cette règle recherche trois combinaisons annotation-attribut dans lesquelles une classe de convertisseur est nécessaire pour transformer les données entre la base de données et l'entité :
javax.persistence.Temporal(TemporalType.TIMESTAMP) sur un attribut java.sql.Datejavax.persistence.Temporal(TemporalType.DATE) sur un attribut java.sql.Timestampjavax.persistence.Temporal(TemporalType.TIME) sur un attribut java.sql.Timestamp
Lorsqu'aucune conversion n'est nécessaire et que l'annotation Temporal peut être retirée, voir la règle Retirer l'annotation Temporal pour certains attributs java.sql.
Dans ce cas, la règle marque l'annotation Temporal(TemporalType.TIMESTAMP).
@javax.persistence.Temporal(TemporalType.TIMESTAMP) private java.sql.Date date ;
Pour résoudre ce problème, créez une classe utilitaire de convertisseur commune, utilisable pour tous les attributs nécessitant ce convertisseur :
Converter qui convertit une date en horodatage, comme dans l'exemple suivant :
import java.sql.Date; import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import javax.persistence.AttributeConverter; import javax.persistence.Converter; @Converter public class DateTimestampConverter implements AttributeConverter<Date, Timestamp> { @Override public Timestamp convertToDatabaseColumn(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); return new Timestamp(cal.getTime().getTime()); } @Override public Date convertToEntityAttribute(Timestamp timestamp) { return new Date(timestamp.getTime()); } }
Temporal(TemporalType.TIMESTAMP) associée à l'attribut java.sql.Date par une annotation Convert dans laquelle l'attribut converter est défini sur la nouvelle classe de convertisseur.
L'exemple suivant présente l'annotation Temporal(TemporalType.TIMESTAMP) d'origine :
import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity classe publique TemporalEntityOJ { @Id ID int privé ; @Temporal(TemporalType.TIMESTAMP) private java.sql.Date sqlDateTIMESTAMP; }
L'exemple suivant présente la nouvelle annotation Convert :
import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity classe publique TemporalEntityOJ { @Id ID int privé ; @Convert(converter=DateTimestampConverter.class) privé java.sql.Date sqlDateTIMESTAMP; }
Dans ce cas, la règle marque l'annotation Temporal(TemporalType.DATE).
@javax.persistence.Temporal(TemporalType.DATE) private java.sql.Timestamp horodatage ;
Pour résoudre ce problème, créez une classe utilitaire de convertisseur commune, utilisable pour tous les attributs nécessitant ce convertisseur :
Converter qui convertit un horodatage en date, comme dans l'exemple suivant :
import java.sql.Date; import java.sql.Timestamp; import javax.persistence.AttributeConverter; import javax.persistence.Converter; @Converter classe publique TimestampDateAnnConverter implémente AttributeConverter< Horodatage, Date> { @Override public Date convertToDatabaseColumn(Timestamp ts) { renvoie la nouvelle date (ts.getTime ()) ; } @Override public Timestamp convertToEntityAttribute(date) { renvoie un nouvel horodatage (date.getTime ()) ; } }
Temporal(TemporalType.DATE) associée à l'attribut java.sql.Timestamp par une annotation Convert dans laquelle l'attribut converter est défini sur la nouvelle classe de convertisseur.
L'exemple suivant présente l'annotation Temporal(TemporalType.DATE) d'origine :
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity classe publique TemporalEntityOJ { @Id ID int privé ; @Temporal(TemporalType.DATE) private java.sql.Timestamp sqlTimestampDate; }
L'exemple suivant présente la nouvelle annotation Convert :
import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity classe publique TemporalEntityOJ { @Id ID int privé ; @Convert(converter=TimestampDateAnnConverter.class) privé java.sql.Timestamp sqlTimestampDate; }
Dans ce cas, la règle marque l'annotation Temporal(TemporalType.TIME).
@javax.persistence.Temporal(TemporalType.TIME) private java.sql.Timestamp horodatage ;
Pour résoudre ce problème, créez une classe utilitaire de convertisseur commune, utilisable pour tous les attributs nécessitant ce convertisseur :
Converter qui convertit un horodatage en heure, comme dans l'exemple suivant :
import java.sql.Time; import java.sql.Timestamp; import javax.persistence.AttributeConverter; import javax.persistence.Converter; @Converter classe publique TimestampTimeAnnConverter implémente AttributeConverter< Horodatage, Temps> { @Override public Time convertToDatabaseColumn(Timestamp ts) { renvoie le nouveau Time (ts.getTime ()) ; } @Override public Timestamp convertToEntityAttribute(Heure) { renvoie un nouvel horodatage (time.getTime ()) ; } }
Temporal(TemporalType.TIME) associée à l'attribut java.sql.Timestamp par une annotation Convert dans laquelle l'attribut converter est défini sur la nouvelle classe de convertisseur.
L'exemple suivant présente l'annotation Temporal(TemporalType.TIME) d'origine :
import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity classe publique TemporalEntityOJ { @Id ID int privé ; @Temporal(TemporalType.TIME) private java.sql.Timestamp sqlTimestampTime; }
L'exemple suivant présente la nouvelle annotation Convert :
import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity classe publique TemporalEntityOJ { @Id ID int privé ; @Convert(converter=TimestampTimeAnnConverter.class) private java.sql.Timestamp sqlTimestampTime; }
Pour des informations sur ce problème et d'autres problèmes de migration d'OpenJPA vers EclipseLink, voir le guide OpenJPA to EclipseLink JPA Migration: Mappings.