Substituir a anotação Temporal com uma anotação do Conversor para alguns atributos java.sql

O OpenJPA persiste os campos dos atributos do tipo java.sql.Date, java.sql.Time, ou java.sql.Timestamp que possuem uma anotaçãojavax.persistence.Temporal, enquanto o EclipseLink lança uma exceção.

Para algumas combinações da anotação javax.persistence.Temporal e os atributos java.sql.Date, java.sql.Time e java.sql.Timestamp, você deve incluir o código conversor de forma que o EclipseLink seja compatível com as tabelas que foram criadas pelo OpenJPA.

Esta regra faz a varredura para encontrar três combinações de anotação-atributo nas quais uma classe conversora é necessária para transformar os dados entre o banco de dados e a entidade:

Para casos nos quais nenhuma conversão é necessária e a anotação Temporal pode ser removida, veja a regra Remover anotação Temporal para alguns atributos java.sql.

@Temporal(TemporalType.TIMESTAMP) em um atributo java.sql.Date

Neste caso, a regra sinaliza a anotação Temporal(TemporalType.TIMESTAMP).

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

Para resolver este problema, crie uma classe de utilitário conversor comum que pode ser usada para todos os atributos que precisam deste conversor:

  1. Crie uma classe Converter que converte uma data em um registro de data e hora, tal como o exemplo a seguir.
    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. Inclua a classe de conversor na definição da unidade de persistência.
  3. Substitua a anotação Temporal(TemporalType.TIMESTAMP) no atributo java.sql.Date com uma anotação Convert que possui o atributo converter configurado para a nova classe conversora.

    O exemplo a seguir mostra a anotação Temporal(TemporalType.TIMESTAMP) original:

    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;
    }
    

    O exemplo a seguir mostra a nova anotação 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) em um atributo java.sql.Timestamp

Neste caso, a regra sinaliza a anotação Temporal(TemporalType.DATE).

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

Para resolver este problema, crie uma classe de utilitário conversor comum que possa ser usada para todos os atributos que precisam deste conversor:

  1. Crie uma classe Converter que converte um registro de data e hora em uma data, tal como o exemplo a seguir.
    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. Inclua a classe de conversor na definição da unidade de persistência.
  3. Substitua a anotação Temporal(TemporalType.DATE) no atributo java.sql.Timestamp com uma anotação Convert que possui o atributo converter configurado para a nova classe conversora.

    O exemplo a seguir mostra a anotação Temporal(TemporalType.DATE) original:

    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;
    }
    

    O exemplo a seguir mostra a nova anotação 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) em um atributo java.sql.Timestamp

Neste caso, a regra sinaliza a anotação Temporal(TemporalType.TIME).

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

Para resolver este problema, crie uma classe de utilitário conversor comum que possa ser usada para todos os atributos que precisam deste conversor:

  1. Crie uma classe Converter que converte um registro de data e hora para um horário, tal como o exemplo a seguir.
    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. Inclua a classe de conversor na definição da unidade de persistência.
  3. Substitua a anotação Temporal(TemporalType.TIME) no atributo java.sql.Timestamp com uma anotação Convert que possui o atributo converter configurado para a nova classe conversora.

    O exemplo a seguir mostra a anotação Temporal(TemporalType.TIME) original:

    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;
    }
    

    O exemplo a seguir mostra a nova anotação 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;
    }
    

Para obter informações sobre esse problema e outros problemas de migração do OpenJPA para o EclipseLink, consulte o guia Migração do OpenJPA para o EclipseLink JPA: mapeamentos.