将某些 java.sql 属性的 Temporal 注释替换为 Converter 注释

OpenJPA 会持久保存类型为 java.sql.Datejava.sql.Timejava.sql.Timestamp 且包含 javax.persistence.Temporal 注释的属性的字段,而 EclipseLink 抛出异常。

对于 javax.persistence.Temporal 注释与 java.sql.Datejava.sql.Timejava.sql.Timestamp 属性的某些组合,必须添加转化器代码以便 EclipseLink 与通过 OpenJPA 创建的表兼容。

此规则会扫描三个“注释/属性”组合,在这些组合中需要转换器类,以便在数据库和实体之间转换数据:

对于不需要转换而且可移除 Temporal 注释的情况,请参阅移除某些 java.sql 属性的 Temporal 注释规则。

java.sql.Date 属性上的 @Temporal(TemporalType.TIMESTAMP)

在这种情况下,规则将标记 Temporal(TemporalType.TIMESTAMP) 注释。

   @javax.persistence.Temporal(TemporalType。TIMESTAMP) 专用 java.sql.Date 日期;

要解决该问题,创建可用于需要该转换器的所有属性的公共 converter 实用程序类:

  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. 将 converter 类添加到持久性单元定义。
  3. java.sql.Date 属性上的 Temporal(TemporalType.TIMESTAMP) 注释替换为将 converter 属性设置为新的 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
    公用类 TemporalEntityOJ {
        @Id private int 标识;
        @Temporal(TemporalType.TIMESTAMP) 专用 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
    公用类 TemporalEntityOJ {
        @Id private int 标识;
        @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 时间戳记;

要解决该问题,创建可用于需要该转换器的所有属性的公共 converter 实用程序类:

  1. 创建将时间戳记转换为日期的 Converter 类,例如以下示例。
    导入 java.sql.Date;
    导入 java.sql.Timestamp;
    导入 javax.persistence.AttributeConverter;
    导入 javax.persistence.Converter;
    
    @Converter
    公共类 TimestampDateAnnConverter implements AttributeConverter<Timestamp, Date>{
        @Override
        公共 Date convertToDatabaseColumn(Timestamp ts) {
            返回新 Date(ts.getTime());
        }
    
        @Override
        公共 Timestamp convertToEntityAttribute(Date date) {
            返回新 Timestamp(date.getTime());
        }
    }
    
  2. 将 converter 类添加到持久性单元定义。
  3. java.sql.Timestamp 属性上的 Temporal(TemporalType.DATE) 注释替换为将 converter 属性设置为新的 converter 类的 Convert 注释。

    以下示例显示了 Temporal(TemporalType.DATE) 注释:

    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    公用类 TemporalEntityOJ {
        @Id private int 标识;
        @Temporal(TemporalType.DATE) 专用 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
    公用类 TemporalEntityOJ {
        @Id private int 标识;
        @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 时间戳记;

要解决该问题,创建可用于需要该转换器的所有属性的公共 converter 实用程序类:

  1. 创建将时间戳记转换为时间的 Converter 类,例如以下示例。
    导入 java.sql.Time;
    导入 java.sql.Timestamp;
    导入 javax.persistence.AttributeConverter;
    导入 javax.persistence.Converter;
    
    @Converter
    公共类 TimestampTimeAnnConverter 实现 AttributeConverter<Timestamp, Time>{
        @Override
        公共时间 convertToDatabaseColumn(Timestamp ts) {
            返回新 Time(ts.getTime());
        }
    
        @Override
        公共 Timestamp convertToEntityAttribute(Time time) {
            返回新 Timestamp(time.getTime());
        }
    }
    
  2. 将 converter 类添加到持久性单元定义。
  3. java.sql.Timestamp 属性上的 Temporal(TemporalType.TIME) 注释替换为将 converter 属性设置为新的 converter 类的 Convert 注释。

    以下示例显示了 Temporal(TemporalType.TIME) 注释:

    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    
    @Entity
    公用类 TemporalEntityOJ {
        @Id private int 标识;
        @Temporal(TemporalType.TIME) 专用 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
    公用类 TemporalEntityOJ {
        @Id private int 标识;
        @Convert(converter=TimestampTimeAnnConverter.class) private java.sql.Timestamp sqlTimestampTime;}
    

有关此问题和其他 OpenJPA 到 EclipseLink 迁移问题的信息,请参阅 OpenJPA to EclipseLink JPA Migration: Mappings 指南。