Sostituzione dell'annotazione Temporal con un'annotazione Converter per alcuni attributi java.sql

OpenJPA conserva i campi degli attributi di tipo java.sql.Date, java.sql.Time o java.sql.Timestamp che hanno un'annotazione javax.persistence.Temporal, mentre EclipseLink genera un'eccezione.

Per alcune combinazioni dell'annotazione javax.persistence.Temporal e degli attributi java.sql.Date, java.sql.Time e java.sql.Timestamp, è necessario aggiungere del codice di conversione in modo che EclipseLink sia compatibile con le tabelle create da OpenJPA.

Questa regola ricerca tre combinazioni di annotazione-attributo in cui è necessaria una classe converter per trasformare i dati tra il database e l'entità:

Per i casi in cui non è necessaria alcuna conversione e l'annotazione Temporal può essere rimossa, consultare la regola Rimozione dell'annotazione Temporal per alcuni attributi java.sql.

@Temporal(TemporalType.TIMESTAMP) in un attributo java.sql.Date

In questo caso, la regola contrassegna l'annotazione Temporal(TemporalType.TIMESTAMP).

   @javax.persistence.Temporal(TemporalType.TIMESTAMP)
   private java.sql.Date date;

Per risolvere questo problema, creare una classe di utilità di conversione comune che può essere utilizzata per tutti gli attributi che necessitano di questa conversione:

  1. Creare una classe Converter che converta una data in una data/ora, come nel seguente esempio.
    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. Aggiungere la classe converter alla definizione dell'unità di persistenza.
  3. Sostituire l'annotazione Temporal(TemporalType.TIMESTAMP) nell'attributo java.sql.Date con un'annotazione Convert che abbia l'attributo converter impostato con la nuova classe converter.

    Il seguente esempio mostra l'annotazione Temporal(TemporalType.TIMESTAMP) originale:

    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
    public class TemporalEntityOJ {
        @Id
        private int id;
        @Temporal(TemporalType.TIMESTAMP)
        private java.sql.Date sqlDateTIMESTAMP;
    }
    

    Il seguente esempio mostra la nuova annotazione 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
    public class TemporalEntityOJ {
        @Id
        private int id;
        @Convert(converter=DateTimestampConverter.class)
        private java.sql.Date sqlDateTIMESTAMP;
    }
    

@Temporal(TemporalType.DATE) in un attributo java.sql.Timestamp

In questo caso, la regola contrassegna l'annotazione Temporal(TemporalType.DATE).

   @javax.persistence.Temporal(TemporalType.DATE)
   private java.sql.Timestamp timestamp;

Per risolvere questo problema, creare una classe di utilità di conversione comune che può essere utilizzata per tutti gli attributi che necessitano di questa conversione:

  1. Creare una classe Converter che converta una data/ora in una data, come nel seguente esempio.
    import java.sql.Date;
    import java.sql.Timestamp;
    import javax.persistence.AttributeConverter;
    import javax.persistence.Converter;
    
    @Converter
    public class TimestampDateAnnConverter implements AttributeConverter<Timestamp, Date>{
        @Override
        public Date convertToDatabaseColumn(Timestamp ts) {
            return new Date(ts.getTime());
        }
    
        @Override
        public Timestamp convertToEntityAttribute(Date date) {
            return new Timestamp(date.getTime());
        }
    }
    
  2. Aggiungere la classe converter alla definizione dell'unità di persistenza.
  3. Sostituire l'annotazione Temporal(TemporalType.DATE) nell'attributo java.sql.Timestamp con un'annotazione Convert che abbia l'attributo converter impostato con la nuova classe converter.

    Il seguente esempio mostra l'annotazione Temporal(TemporalType.DATE) originale:

    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    public class TemporalEntityOJ {
        @Id
        private int id;
        @Temporal(TemporalType.DATE)
        private java.sql.Timestamp sqlTimestampDate;
    }
    

    Il seguente esempio mostra la nuova annotazione 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
    public class TemporalEntityOJ {
        @Id
        private int id;
        @Convert(converter=TimestampDateAnnConverter.class)
        private java.sql.Timestamp sqlTimestampDate;
    }
    

@Temporal(TemporalType.TIME) in un attributo java.sql.Timestamp

In questo caso, la regola contrassegna l'annotazione Temporal(TemporalType.TIME).

   @javax.persistence.Temporal(TemporalType.TIME)
   private java.sql.Timestamp timestamp;

Per risolvere questo problema, creare una classe di utilità di conversione comune che può essere utilizzata per tutti gli attributi che necessitano di questa conversione:

  1. Creare una classe Converter che converta una data/ora in un'ora, come nel seguente esempio.
    import java.sql.Time;
    import java.sql.Timestamp;
    import javax.persistence.AttributeConverter;
    import javax.persistence.Converter;
    
    @Converter
    public class TimestampTimeAnnConverter implements AttributeConverter<Timestamp, Time>{
        @Override
        public Time convertToDatabaseColumn(Timestamp ts) {
            return new Time(ts.getTime());
        }
    
        @Override
        public Timestamp convertToEntityAttribute(Time time) {
            return new Timestamp(time.getTime());
        }
    }
    
  2. Aggiungere la classe converter alla definizione dell'unità di persistenza.
  3. Sostituire l'annotazione Temporal(TemporalType.TIME) nell'attributo java.sql.Timestamp con un'annotazione Convert che abbia l'attributo converter impostato con la nuova classe converter.

    Il seguente esempio mostra l'annotazione Temporal(TemporalType.TIME) originale:

    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    public class TemporalEntityOJ {
        @Id
        private int id;
        @Temporal(TemporalType.TIME)
        private java.sql.Timestamp sqlTimestampTime;
    }
    

    Il seguente esempio mostra la nuova annotazione 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
    public class TemporalEntityOJ {
        @Id
        private int id;
        @Convert(converter=TimestampTimeAnnConverter.class)
        private java.sql.Timestamp sqlTimestampTime;
    }
    

Per informazioni su questo problema e altri problemi della migrazione da OpenJPA a EclipseLink, consultare la guida OpenJPA to EclipseLink JPA Migration: Mappings.