OpenJPA persists the fields of attributes of type java.sql.Date, java.sql.Time, or
java.sql.Timestamp that have a javax.persistence.Temporal annotation, whereas EclipseLink throws an exception.
For some combinations of the javax.persistence.Temporal annotation and the
java.sql.Date, java.sql.Time, and
java.sql.Timestamp attributes,
you must add converter code so that EclipseLink
is compatible with the tables that were created by OpenJPA.
This rule scans for three annotation-attribute combinations where a converter class is needed to transform the data between the database and the entity:
javax.persistence.Temporal(TemporalType.TIMESTAMP)
annotation on a java.sql.Date attributejavax.persistence.Temporal(TemporalType.DATE)
annotation on a java.sql.Timestamp attributejavax.persistence.Temporal(TemporalType.TIME)
annotation on a java.sql.Timestamp attribute
For cases where no conversion is needed and the Temporal annotation
can be removed, see the
Remove Temporal annotation for some java.sql attributes
rule.
In this case, the rule flags the Temporal(TemporalType.TIMESTAMP) annotation.
@javax.persistence.Temporal(TemporalType.TIMESTAMP)
private java.sql.Date date;
To resolve this issue, create a common converter utility class that can be used for all attributes that need this converter:
Converter class
that converts a date to a time stamp, such as the following example.
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()); } }
Temporal(TemporalType.TIMESTAMP) annotation on the
java.sql.Date attribute with a Convert annotation
that has the converter attribute set to the new converter class.
The following example shows the original Temporal(TemporalType.TIMESTAMP) annotation:
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; }
The following example shows the new Convert annotation:
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; }
In this case, the rule flags the Temporal(TemporalType.DATE) annotation.
@javax.persistence.Temporal(TemporalType.DATE)
private java.sql.Timestamp timestamp;
To resolve this issue, create a common converter utility class that can be used for all attributes needing this converter:
Converter class that
converts a time stamp to a date, such as the following example.
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()); } }
Temporal(TemporalType.DATE) annotation on the
java.sql.Timestamp attribute with a Convert annotation
that has the converter attribute set to the new converter class.
The following example shows the original Temporal(TemporalType.DATE) annotation:
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; }
The following example shows the new Convert annotation:
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; }
In this case, the rule flags the Temporal(TemporalType.TIME) annotation.
@javax.persistence.Temporal(TemporalType.TIME)
private java.sql.Timestamp timestamp;
To resolve this issue, create a common converter utility class that can be used for all attributes needing this converter:
Converter class that converts a time stamp to a time
such as the following example.
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()); } }
Temporal(TemporalType.TIME) annotation on the
java.sql.Timestamp attribute with a Convert annotation
that has the converter attribute set to the new converter class.
The following example shows the original Temporal(TemporalType.TIME) annotation:
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; }
The following example shows the new Convert annotation:
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; }
For information about this issue and other OpenJPA to EclipseLink migration issues, see the OpenJPA to EclipseLink JPA Migration: Mappings guide.