Temporal-Annotation für einige java.sql-Attribute durch eine Converter-Annotation ersetzen

OpenJPA speichert die Felder von Attributen des Typs java.sql.Date, java.sql.Time und java.sql.Timestamp, die eine Annotation javax.persistence.Temporal haben, persistent, wohingegen EclipseLink eine Ausnahme auslöst.

Für einige Kombinationen der Annotation javax.persistence.Temporal und der Attribute java.sql.Date, java.sql.Time und java.sql.Timestamp müssen Sie Converter-Code hinzufügen, damit EclipseLink mit den von OpenJPA erstellten Tabellen kompatibel ist.

Diese Regel sucht nach drei Annotation-Attribut-Kombinationen, in denen eine Converter-Klasse erforderlich ist, um die Daten zwischen der Datenbank und der Entität zu transformieren:

In den Fällen, in denen keine Konvertierung erforderlich ist und die Annotation Temporal entfernt werden kann, verwenden Sie die Regel Temporal-Annotation für einige java.sql-Attribute entfernen.

@Temporal(TemporalType.TIMESTAMP) in einem java.sql.Date-Attribut

In diesem Fall markiert die Regel die Annotation Temporal(TemporalType.TIMESTAMP).

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

Zur Behebung dieses Problems erstellen Sie eine allgemeine Converter-Dienstprogrammklasse, die für alle Attribute verwendet werden kann, die diesen Converter benötigen:

  1. Erstellen Sie eine Converter-Klasse, die ein Datum in eine Zeitmarke konvertiert, wie im folgenden Beispiel gezeigt.
    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. Fügen Sie der Persistenzeinheitendefinition die Converter-Klasse hinzu.
  3. Ersetzen Sie die Annotation Temporal(TemporalType.TIMESTAMP) im Attribut java.sql.Date durch eine Annotation Convert, in der das Attribut converter auf die neue Converter-Klasse gesetzt ist.

    Das folgende Beispiel zeigt die ursprüngliche Annotation Temporal(TemporalType.TIMESTAMP):

    import javax.persistence.Convert;
    import javax.persistence.Entity;
    import javax.persistence.Id
    import javax.persistence.Table
    importieren javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    Allgemein zugängliche Klasse TemporalEntityOJ {
        @Id private int id;
        @Temporal(TemporalType.TIMESTAMP) private java.sql.Datum sqlDateTIMESTAMP;}
    

    Das folgende Beispiel zeigt die neue Annotation Convert:

    import javax.persistence.Convert;
    import javax.persistence.Entity;
    import javax.persistence.Id
    import javax.persistence.Table
    importieren javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    Allgemein zugängliche Klasse TemporalEntityOJ {
        @Id private int id;
        @Convert(converter=DateTimestampConverter.class) private java.sql.Date sqlDateTIMESTAMP;}
    

@Temporal(TemporalType.DATE) in einem java.sql.Timestamp-Attribut

In diesem Fall markiert die Regel die Annotation Temporal(TemporalType.DATE).

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

Zur Behebung dieses Problems erstellen Sie eine allgemeine Converter-Dienstprogrammklasse, die für alle Attribute verwendet werden kann, die diesen Converter benötigen:

  1. Erstellen Sie eine Converter-Klasse, die eine Zeitmarke in ein Datum konvertiert, wie im folgenden Beispiel gezeigt.
    import java.sql.Date;
    import java.sql.Timestamp;
    import javax.persistence.AttributeConverter;
    import javax.persistence.Converter;
    
    @Converter
    public class TimestampDateAnnConverter implementiert AttributeConverter< Timestamp, Date> {
        @Override public Datum convertToDatabaseColumn(Zeitmarke ts) { return new Datum (ts.getTime ());
        }
    
        @Override public Zeitmarke convertToEntityAttribute(Datumsdatum) { return new Zeitmarke (date.getTime ());
        }}
    
  2. Fügen Sie der Persistenzeinheitendefinition die Converter-Klasse hinzu.
  3. Ersetzen Sie die Annotation Temporal(TemporalType.DATE) im Attribut java.sql.Timestamp durch eine Annotation Convert, in der das Attribut converter auf die neue Converter-Klasse gesetzt ist.

    Das folgende Beispiel zeigt die ursprüngliche Annotation Temporal(TemporalType.DATE):

    import javax.persistence.Entity;
    import javax.persistence.Id
    importieren javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    Allgemein zugängliche Klasse TemporalEntityOJ {
        @Id private int id;
        @Temporal(TemporalType.DATE) private java.sql.Timestamp sqlTimestampDate;}
    

    Das folgende Beispiel zeigt die neue Annotation Convert:

    import javax.persistence.Convert;
    import javax.persistence.Entity;
    import javax.persistence.Id
    import javax.persistence.Table
    importieren javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    Allgemein zugängliche Klasse TemporalEntityOJ {
        @Id private int id;
        @Convert(converter=ZeitmarkeDateAnnConverter.class) private java.sql.Timestamp sqlTimestampDate;}
    

@Temporal(TemporalType.TIME) in einem java.sql.Timestamp-Attribut

In diesem Fall markiert die Regel die Annotation Temporal(TemporalType.TIME).

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

Zur Behebung dieses Problems erstellen Sie eine allgemeine Converter-Dienstprogrammklasse, die für alle Attribute verwendet werden kann, die diesen Converter benötigen:

  1. Erstellen Sie eine Converter-Klasse, die eine Zeitmarke in eine Zeitangabe konvertiert, wie im folgenden Beispiel gezeigt.
    import java.sql.Time
    import java.sql.Timestamp;
    import javax.persistence.AttributeConverter;
    import javax.persistence.Converter;
    
    @Converter
    public class TimestampTimeAnnConverter implementiert AttributeConverter< Zeitmarke, Time> {
        @Override öffentliche Zeit convertToDatabaseColumn(Zeitmarke ts) { return new Zeit (ts.getTime ());
        }
    
        @Override public Zeitmarke convertToEntityAttribute(Zeit) { return new Zeitmarke (time.getTime ());
        }}
    
  2. Fügen Sie der Persistenzeinheitendefinition die Converter-Klasse hinzu.
  3. Ersetzen Sie die Annotation Temporal(TemporalType.TIME) im Attribut java.sql.Timestamp durch eine Annotation Convert, in der das Attribut converter auf die neue Converter-Klasse gesetzt ist.

    Das folgende Beispiel zeigt die ursprüngliche Annotation Temporal(TemporalType.TIME):

    import javax.persistence.Entity;
    import javax.persistence.Id
    importieren javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    Allgemein zugängliche Klasse TemporalEntityOJ {
        @Id private int id;
        @Temporal(TemporalType.TIME) private java.sql.Timestamp sqlTimestamp;}
    

    Das folgende Beispiel zeigt die neue Annotation Convert:

    import javax.persistence.Convert;
    import javax.persistence.Entity;
    import javax.persistence.Id
    import javax.persistence.Table
    importieren javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    Allgemein zugängliche Klasse TemporalEntityOJ {
        @Id private int id;
        @Convert(converter=TimestampTimeAnnConverter.class) private java.sql.Timestamp sqlTimestampTime;}
    

Informationen zu diesem Problem und zu weiteren Problemen bei der Migration von OpenJPA auf EclipseLink finden Sie in der Veröffentlichung OpenJPA to EclipseLink JPA Migration: Mappings.