Remplacer l'annotation Temporal par une annotation Converter pour certains attributs java.sql

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é :

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.

@Temporal(TemporalType.TIMESTAMP) sur un attribut java.sql.Date

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 :

  1. Créez une classe 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());
        }
    }
    
  2. Ajoutez la classe de convertisseur à la définition d'unité de persistance.
  3. Remplacer l'annotation 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; }
    

@Temporal(TemporalType.DATE) on a java.sql.Timestamp attribute

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 :

  1. Créez une classe 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 ()) ;
        } }
    
  2. Ajoutez la classe de convertisseur à la définition d'unité de persistance.
  3. Remplacer l'annotation 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; }
    

@Temporal(TemporalType.TIME) on a java.sql.Timestamp attribute

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 :

  1. Créez une classe 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 ()) ;
        } }
    
  2. Ajoutez la classe de convertisseur à la définition d'unité de persistance.
  3. Remplacer l'annotation 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.