Как использовать Joda Time с JPA (eclipselink)? - PullRequest
14 голосов
/ 20 марта 2012

Я пытался использовать DataTime в своем классе entity.Добавляя @Temporal(TemporalType.DATE) над полем, я получил сообщение об ошибке: "Постоянное поле или свойство для временного типа должно иметь тип 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 .Ответ, предлагающий использовать Hibernate, но я должен использовать eclipselink.Я могу использовать объект DateTime в своем классе сущностей с представлением БД как BLOB, но мне нужно это как Date.Есть что-нибудь вроде jodatime-eclipselink?Или любое другое предложение?Спасибо за помощь.

Ответы [ 7 ]

15 голосов
/ 20 марта 2012

Базовая ссылка определяет конвертер EclipseLink для преобразования из Joda DateTime в java.sql.Timestamp или Date. Вы можете использовать его или определить свой собственный конвертер и использовать его через @Convert, @Converter в EclipseLink.

Для создания DDL конвертер должен определить метод инициализации и установить тип в поле отображения на java.sql.Timestamp.

Пожалуйста, зарегистрируйте ошибку (или проголосуйте за существующую) на EclipseLink, у нас должна быть поддержка Joda.

6 голосов
/ 18 июня 2012

Я пытаюсь использовать joda-time-eclipselink-интеграцию, но не работает, вероятно, я сделал что-то не так,

Поэтому я провел больше исследований и нашел эту ссылку http://jcodehelp.blogspot.com.br/2011/12/persist-joda-datetime-with-eclipselink.html, они используют@ Конвертер аннотации для преобразования Joda Date Time.

Я пытаюсь и работает для меня, я надеюсь, работает и для вас.

4 голосов
/ 11 мая 2012

Я хотел сделать то же самое, и поиск в Google фактически привел меня сюда.Мне удалось сделать это с помощью аннотации @Access.Во-первых, вы аннотируете класс следующим образом:

@Access(AccessType.FIELD)
public class MyClass
{
    ....

Это обеспечивает доступ к полям для всего, поэтому вам не нужно аннотировать поля по отдельности.Затем вы создаете метод получения и установки для использования 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 пытаться сохраняться и с поля.

Это должно выполнить то, что вы пытаетесь сделать.Это прекрасно сработало для меня.

2 голосов
/ 08 мая 2012

Ахамед, вы упомянули, что это не работает для вас.Кроме того, вам необходимо переопределить метод инициализации преобразователя, чтобы определить нужный тип поля:

@Override
public void initialize(DatabaseMapping mapping, Session session) {
    ((AbstractDirectMapping) mapping)
            .setFieldClassification(java.sql.Timestamp.class);
}
1 голос
/ 17 сентября 2015

Ниже приведен рабочий пример, основанный на ответах, доступных в теме

В принципе, самый простой подход - использовать EclipseLink @Converter для поля DateTime в вашей сущности.

Использование конвертера выглядит следующим образом:

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

}

Я добавляю это с целью простого copy-и паста раствор.

0 голосов
/ 18 марта 2016

Ответ от Atais работает хорошо. Ниже обновление до него.

Вы можете опустить аннотацию @converter, зарегистрировав ее глобально. В файле persistance.xml в блоке persitence добавьте:

<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, то вы можете пропустить даже первый шаг, потому что он является настройкой по умолчанию для всех модулей сохраняемости.

0 голосов
/ 20 марта 2012
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...