將某些 java.sql 屬性的 Temporal 註釋取代為 Converter 註釋

OpenJPA 會持續保存屬性類型為 java.sql.Datejava.sql.Timejava.sql.Timestamp 且具有 javax.persistence.Temporal 註釋之屬性的欄位,而 EclipseLink 則會擲出異常狀況。

針對某些 javax.persistence.Temporal 註釋與 java.sql.Datejava.sql.Time 以及 java.sql.Timestamp 屬性的組合,您必須新增轉換器程式碼,EclipseLink 才能與 OpenJPA 所建立的表格相容。

此規則會掃描三種註釋/屬性組合,且需要轉換器類別才能在資料庫與實體之間轉換資料:

如果不需要轉換且可以移除 Temporal 註釋,請參閱針對某些 java.sql 屬性移除 Temporal 註釋規則。

java.sql.Date 屬性中的 @Temporal(TemporalType.TIMESTAMP)

在本例中,規則會標示 Temporal(TemporalType.TIMESTAMP) 註釋。

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

要解決這個問題,請建立一個可用於需要此轉換器之所有屬性的通用轉換器公用程式類別:

  1. 建立 Converter 類別將日期轉換成時間戳記,如下例所示。
    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. 將轉換器類別新增至持續性單元定義。
  3. java.sql.Date 屬性中的 Temporal(TemporalType.TIMESTAMP) 註釋取代為將 converter 屬性設為新的轉換器類別的 Convert 註釋。

    下例顯示原來的 Temporal(TemporalType.TIMESTAMP) 註釋:

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

    下例顯示新的 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;}
    

java.sql.Timestamp 屬性中的 @Temporal(TemporalType.DATE)

在本例中,規則會標示 Temporal(TemporalType.DATE) 註釋。

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

要解決這個問題,請建立一個可用於需要此轉換器之所有屬性的通用轉換器公用程式類別:

  1. 建立 Converter 類別將時間戳記轉換成日期,如下例所示。
    匯入 java.sql.Date;
    匯入 java.sql.Timestamp;
    匯入 javax.persistence.AttributeConverter;
    匯入 javax.persistence.Converter;
    
    @Converter
    Public class TimestampDateAnnConverter implements AttributeConverter<Timestamp, Date>{
        @Override
        公用 Date convertToDatabaseColumn(Timestamp ts) {
            傳回新的 Date(ts.getTime());
        }
    
        @Override
        公用 Timestamp convertToEntityAttribute(Date date) {
            傳回新的 Timestamp(date.getTime());
        }
    }
    
  2. 將轉換器類別新增至持續性單元定義。
  3. java.sql.Timestamp 屬性中的 Temporal(TemporalType.DATE) 註釋取代為將 converter 屬性設為新的轉換器類別的 Convert 註釋。

    下例顯示原來的 Temporal(TemporalType.DATE) 註釋:

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

    下例顯示新的 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;}
    

java.sql.Timestamp 屬性中的 @Temporal(TemporalType.TIME)

在本例中,規則會標示 Temporal(TemporalType.TIME) 註釋。

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

要解決這個問題,請建立一個可用於需要此轉換器之所有屬性的通用轉換器公用程式類別:

  1. 建立 Converter 類別將時間戳記轉換成時間,如下例所示。
    匯入 java.sql.Time;
    匯入 java.sql.Timestamp;
    匯入 javax.persistence.AttributeConverter;
    匯入 javax.persistence.Converter;
    
    @Converter
    Public class TimestampTimeAnnConverter 實作 AttributeConverter<Timestamp, Time>{
        @Override
        公用時間 convertToDatabaseColumn(Timestamp ts) {
            傳回新的 Time(ts.getTime());
        }
    
        @Override
        公用 Timestamp convertToEntityAttribute(Time time) {
            傳回新的 Timestamp(time.getTime());
        }
    }
    
  2. 將轉換器類別新增至持續性單元定義。
  3. java.sql.Timestamp 屬性中的 Temporal(TemporalType.TIME) 註釋取代為將 converter 屬性設為新的轉換器類別的 Convert 註釋。

    下例顯示原來的 Temporal(TemporalType.TIME) 註釋:

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

    下例顯示新的 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;}
    

如需此問題以及其他 OpenJPA 至 EclipseLink 移轉問題的相關資訊,請參閱 OpenJPA 至 EclipseLink JPA 移轉:對映手冊。