Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在JPA(eclipselink)中使用joda时间?_Java_Jpa_Persistence_Eclipselink_Jodatime - Fatal编程技术网

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

Java 如何在JPA(eclipselink)中使用joda时间?,java,jpa,persistence,eclipselink,jodatime,Java,Jpa,Persistence,Eclipselink,Jodatime,我试图在我的实体类中使用DataTime。在字段上方添加@Temporal(TemporalType.DATE),我得到的错误是“临时类型的持久字段或属性必须是java.util.DATE、java.util.Calendar或java.util.GregorianCalendar类型”。我可以来回介绍转换;按如下方式使用setter和getter: @Temporal(TemporalType.DATE) private Calendar attendanceDate; public Dat

我试图在我的
实体
类中使用
DataTime
。在字段上方添加
@Temporal(TemporalType.DATE)
,我得到的错误是“临时类型的持久字段或属性必须是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());
}
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;
但我希望eclipselink能帮我做这件事。我已经试过了。答案是建议使用hibernate,但我必须使用eclipselink。我可以使用实体类中的
DateTime
对象,DB表示为
BLOB
,但我需要它作为
Date
。有类似于jodatime eclipselink的东西吗?还是其他建议?谢谢您的帮助。

解决方案就在这里

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

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


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

Ahamed,你提到它不适合你。此外,您需要重写转换器的initialize方法以定义所需的字段类型:

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

我也想做同样的事情,谷歌搜索实际上把我带到了这里。我可以通过
@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,如下所示

@Transient
private LocalDate myDate = null;
这也阻止了JPA尝试从字段中持久化


这应该能完成你想做的事情。这对我来说非常有效。

我尝试使用joda time eclipselink集成,但不起作用,可能是我做错了什么

所以我做了更多的研究,发现了这个链接,他们使用@Converter注释来转换Joda日期时间


我努力为我工作,希望也能为你工作。

以下是一个基于本主题中可用答案的工作示例

基本上,最简单的方法是使用EclipseLink
@Converter
作为实体中的
DateTime
字段

转换器的使用情况如下所示:

@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());
}
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;
    }

}
我添加此选项是为了方便复制和粘贴解决方案。

来自的答案效果良好。下面是对它的升级

您可以通过全局注册@converter注释来忽略它。 在Persistence单元中的persistence.xml处添加:

<mapping-file>META-INF/xyz-orm.xml</mapping-file>

如果您的配置文件是
META-INF/orm.xml
,那么您甚至可以省略第一步,因为它是所有persistence单元的默认confing。

虽然这在理论上可以回答这个问题,但在这里包含答案的基本部分,并提供链接供参考。我在那里找到了一个jar文件,它的信息非常少。我应该使用jar文件中唯一的转换器类吗?谢谢你的帮助!仍然JPA将创建一个列作为
BLOB
而不是
DATE
:(它仍然保存一个快照。它似乎没有被维护。关于DDL创建,在我的初始化方法中,我有以下内容:mapping.getField().setSqlType(java.sql.Types.TIMESTAMP);但是,在我的db中创建的类型是varchar(255).知道问题出在哪里吗?@kaciula我通过添加以下内容来解决:
mapping.getField().setType(java.sql.Timestamp.class);
.HTH.我们如何在服务级别(DAO)访问
myDate
?它不能有一个mutator和一个accessor(它们对于
myDateForDB
也是私有的)。我不确定我是否完全理解您的问题。您可以为
LocalDate myDate
设置一个公共getter和setter。由于该类是用
@Access(AccessType.FIELD)注释的。
JPA根本不会查看getter和setter。