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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9783577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:37:20  来源:igfitidea点击:

How to use joda time with JPA (eclipselink)?

javajpapersistenceeclipselinkjodatime

提问by Ahamed

I tried to use the DataTimein my entityclass. Adding @Temporal(TemporalType.DATE)above the field, I got the error saying "The persistent field or property for a Temporal type must be of type java.util.Date, java.util.Calendar or java.util.GregorianCalendar". I can introduce the conversion back and forth; using setters and getters as follows:

我试图DataTime在我的entity课堂上使用。@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());
}

but I hope eclipselinkto do it for me. I have gone thro' Persist Joda-time's DateTime via Hibernate. The answer suggesting to use hibernate, but I have to use eclipselink. I can use the DateTimeobject in my entity class with DB representation as BLOB, but I need it as Date. Is there anything like jodatime-eclipselink? Or any other suggestion? Thanks for the help.

但我希望eclipselink为我做这件事。我已经通过 Hibernate 遍历Persist Joda-time 的 DateTime。答案建议使用休眠,但我必须使用 eclipselink。我可以DateTime在我的实体类中使用 DB 表示形式的对象作为BLOB,但我需要它作为Date. 有什么类似的jodatime-eclipselink吗?或者有什么其他建议?谢谢您的帮助。

采纳答案by James

Basic the link defines an EclipseLink Converter to convert from Joda DateTime to java.sql.Timestamp or Date. You could use it, or define your own converter and use it through @Convert, @Converter in EclipseLink.

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

For DDL creation, the converter should define the initialize method and set the type on the mapping's field to java.sql.Timestamp.

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

Please log a bug (or vote for the existing one) on this in EclipseLink, we should have support for Joda.

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

回答by Ilya

回答by marco

Ahamed, you mentioned it wasn't working for you. Additionally you need to override the initialize method of the converter to define the desired field type:

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

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

回答by dnc253

I wanted to do the same thing, and Googling around actually led me here. I was able to accomplish this using the @Accessannotation. First, you annotate the class like this

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

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

This provides field access to everything so you don't have to annotate the fields individually. Then you create a getter and setter for the JPA to use.

这提供了对所有内容的字段访问,因此您不必单独注释字段。然后创建供 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);
}

The @Access(AccessType.PROPERTY)tells JPA to persist and retrieve through these methods.

@Access(AccessType.PROPERTY)告诉JPA坚持和检索通过这些方法。

Finally, you'll want to mark your member variable as transient as follows

最后,您需要将您的成员变量标记为瞬态,如下所示

@Transient
private LocalDate myDate = null;

This stops JPA from trying to persist from the field as well.

这也阻止了 JPA 试图从该领域坚持下去。

That should accomplish what you're trying to do. It worked great for me.

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

回答by Hugo Prudente

I Try use joda-time-eclipselink-integration, but don't work, problably I made something wrong,

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

So I made more researchs and i found this link http://jcodehelp.blogspot.com.br/2011/12/persist-joda-datetime-with-eclipselink.html, they use @Converter annotation to convert the Joda Date Time.

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

I Try and works for me, I hope, works for you too.

我尝试并为我工作,我希望,也为您工作。

回答by Atais

The following is a working example based on the answers available in the topic

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

Basically the easiest approach is to use EclipseLink @Converterfor a DateTimefield in your Entity.

基本上,最简单的方法是将 EclipseLink@Converter用于DateTime实体中的字段。

The converter usage looks as follows:

转换器用法如下所示:

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;

And the converter itself:

和转换器本身:

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

}

I am adding this for the purpose of easy copy-and-pastesolution.

我添加这个是为了简单的复制和粘贴解决方案。

回答by Waldemar Wosiński

Answer from Ataisworks well. Below an upgrade to it.

Atais 的回答效果很好。下面对它进行升级。

You can omit @converter annotation by registering it globally. At persistance.xml in persitence-unit add:

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

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

and file META-INF/xyz-orm.xmlwith content:

和文件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>

If your config file is META-INF/orm.xmlthen you can omit even first step because it is default confing for all persitence units.

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