Как использовать время Joda с JPA (eclipselink)?
Я попытался использовать DataTime
в моем классе entity
. Добавив @Temporal(TemporalType.DATE)
над полем, я получил сообщение об ошибке "Постоянное поле или свойство типа Temporal должно быть типа java.util.Date, java.util.Calendar или java.util.GregorianCalendar" . Я могу ввести конверсию туда и обратно; используя сеттеры и геттеры следующим образом:
@Temporal(TemporalType.DATE)
private Calendar attendanceDate;
public DateTime getAttendanceDate() {
return new DateTime(this.attendanceDate);
}
public void setAttendanceDate(DateTime attendanceDate) {
this.attendanceDate = attendanceDate.toCalendar(Locale.getDefault());
}
но я надеюсь eclipselink
сделать это для меня. Я ушел в прошлое Переносить DateTime в Joda-time через Hibernate. Ответ, предлагающий использовать спящий режим, но я должен использовать eclipselink. Я могу использовать объект DateTime
в классе сущности с представлением БД как BLOB
, но мне это нужно как Date
. Есть что-нибудь вроде jodatime-eclipselink
? Или любое другое предложение? Спасибо за помощь.
Ответы
Ответ 1
Базовая ссылка определяет конвертер EclipseLink для преобразования из Joda DateTime в java.sql.Timestamp или Date.
Вы можете использовать его или определить свой собственный конвертер и использовать его через @Convert, @Converter в EclipseLink.
Для создания DDL конвертер должен определить метод initialize и задать тип в поле сопоставления java.sql.Timestamp.
Пожалуйста, зарегистрируйте ошибку (или голосуйте за существующую) на этом в EclipseLink, мы должны поддерживать Joda.
Ответ 2
Я пытаюсь использовать joda-time-eclipselink-integration, но не работает, вероятно, я сделал что-то неправильно,
Итак, я сделал больше исследований, и я нашел эту ссылку http://jcodehelp.blogspot.com.br/2011/12/persist-joda-datetime-with-eclipselink.html, они используют аннотацию @Converter для преобразования времени даты Joda.
Я стараюсь и работаю для меня, надеюсь, тоже работает для вас.
Ответ 3
Я хотел сделать то же самое, и Googling вокруг фактически привел меня сюда. Я смог выполнить это, используя аннотацию @Access
. Во-первых, вы комментируете класс, подобный этому
@Access(AccessType.FIELD)
public class MyClass
{
....
Это обеспечивает доступ ко всем полям, поэтому вам не нужно отдельно аннотировать поля. Затем вы создаете getter и setter для использования JPA.
@Column(name="my_date")
@Temporal(TemporalType.DATE)
@Access(AccessType.PROPERTY)
private Date getMyDateForDB()
{
return myDate.toDate();
}
private void setMyDateForDB(Date myDateFromDB)
{
myDate = new LocalDate(myDateFromDB);
}
@Access(AccessType.PROPERTY)
указывает JPA на сохранение и извлечение данных с помощью этих методов.
Наконец, вы захотите пометить переменную-член как переходную, как показано ниже.
@Transient
private LocalDate myDate = null;
Это останавливает попытку JPA также сохранить поле.
Это должно выполнить то, что вы пытаетесь сделать. Это отлично поработало для меня.
Ответ 4
Ахмед, ты сказал, что это не работает для тебя. Кроме того, вам необходимо переопределить метод инициализации конвертера, чтобы определить желаемый тип поля:
@Override
public void initialize(DatabaseMapping mapping, Session session) {
((AbstractDirectMapping) mapping)
.setFieldClassification(java.sql.Timestamp.class);
}
Ответ 5
Ниже приведен рабочий пример, основанный на ответах, доступных в теме
В основном самый простой подход - использовать EclipseLink @Converter
для поля DateTime
в вашем Entity.
Использование конвертера выглядит следующим образом:
import org.eclipse.persistence.annotations.Convert;
import org.eclipse.persistence.annotations.Converter;
import javax.persistence.*;
import org.joda.time.DateTime;
@Entity
public class YourEntity {
@Converter(name = "dateTimeConverter", converterClass = your.package.to.JodaDateTimeConverter.class)
@Convert("dateTimeConverter")
private DateTime date;
И сам конвертер:
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;
import org.joda.time.DateTime;
import java.sql.Timestamp;
public class JodaDateTimeConverter implements Converter {
private static final long serialVersionUID = 1L;
@Override
public Object convertDataValueToObjectValue(Object dataValue, Session session) {
return dataValue == null ? null : new DateTime(dataValue);
}
@Override
public Object convertObjectValueToDataValue(Object objectValue, Session session) {
return objectValue == null ? null : new Timestamp(((DateTime) objectValue).getMillis());
}
@Override
public void initialize(DatabaseMapping mapping, Session session) {
// this method can be empty if you are not creating DB from Entity classes
mapping.getField().setType(java.sql.Timestamp.class);
}
@Override
public boolean isMutable() {
return false;
}
}
Я добавляю это для упрощения копирования и вставки.
Ответ 6
Решение здесь
joda-time-eclipselink-integration
Ответ 7
Ответ от Atais работает хорошо. Ниже обновления до него.
Вы можете опустить аннотацию @converter, зарегистрировав ее по всему миру.
На persistance.xml в persitence-unit добавьте:
<mapping-file>META-INF/xyz-orm.xml</mapping-file>
и файл META-INF/xyz-orm.xml
с контентом:
<?xml version="1.0"?>
<entity-mappings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm" version="2.1">
<converter class="pl.ds.wsc.storage.converter.JodaDateTimeConverter"/>
</entity-mappings>
Если ваш конфигурационный файл META-INF/orm.xml
, вы можете опустить даже первый шаг, потому что он по умолчанию используется для всех единиц времени.