如何在JPA(eclipselink)中使用joda时间?

时间:2012-03-20 08:37:57

标签: java jpa persistence eclipselink jodatime

我尝试在DataTime课程中使用entity。在字段上方添加@Temporal(TemporalType.DATE),我收到错误提示“Temporal类型的持久字段或属性必须是java.util.Date,java.util.Calendar或java.util.GregorianCalendar类型” 即可。我可以来回介绍转换;使用setter和getter如下:

@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为我做这件事。我已经离开了Persist Joda-time's DateTime via Hibernate。答案建议使用hibernate,但我必须使用eclipselink。我可以在我的实体类中使用DateTime对象,数据库表示为BLOB,但我需要它为Date。有jodatime-eclipselink之类的东西吗?还是其他任何建议?谢谢你的帮助。

7 个答案:

答案 0 :(得分:15)

基本链接定义了一个EclipseLink转换器,用于从Joda DateTime转换为java.sql.Timestamp或Date。 您可以使用它,或者定义自己的转换器并通过EclipseLink中的@Convert,@ Confverter使用它。

对于DDL创建,转换器应定义initialize方法并将映射字段上的类型设置为java.sql.Timestamp。

请在EclipseLink中记录一个错误(或对现有错误进行投票),我们应该支持Joda。

答案 1 :(得分:6)

我尝试使用joda-time-eclipselink-integration,但是不行,可能我做错了,

所以我做了更多的研究,我找到了这个链接http://jcodehelp.blogspot.com.br/2011/12/persist-joda-datetime-with-eclipselink.html,他们使用@Converter注释来转换Joda日期时间。

我试着为我工作,我希望,也适合你。

答案 2 :(得分:4)

我想做同样的事情,谷歌搜索实际上把我带到了这里。我能够使用@Access注释完成此操作。首先,你像这样注释类

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

这提供了对所有内容的字段访问权限,因此您不必单独注释字段。然后为JPA创建一个getter和setter来使用。

@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尝试从该字段中继续存在。

那应该完成你想要做的事情。它对我很有用。

答案 3 :(得分:2)

艾哈迈德,你提到它不适合你。此外,您需要覆盖转换器的initialize方法以定义所需的字段类型:

@Override
public void initialize(DatabaseMapping mapping, Session session) {
    ((AbstractDirectMapping) mapping)
            .setFieldClassification(java.sql.Timestamp.class);
}

答案 4 :(得分:1)

以下是基于主题

中提供的答案的工作示例

基本上最简单的方法是将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;
    }

}

我添加此内容是为了便于复制粘贴解决方案。

答案 5 :(得分:0)

解决方案在这里 joda-time-eclipselink-integration

答案 6 :(得分:0)

来自Atais的回答很有效。在升级之下。

您可以通过全局注册来省略@converter注释。 在Persitence-pers的persistance.xml中添加:

<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,那么你甚至可以省略第一步,因为它是所有persitence单位的默认配置。