How to use joda time with JPA (eclipselink)?

依然范特西╮ 提交于 2019-11-28 09:52:46

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.

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

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

Hugo Prudente

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

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.

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

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

@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.

@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.

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.

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

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:

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

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

Basically the easiest approach is to use EclipseLink @Converter for a DateTime field in your Entity.

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-paste solution.

Ilya
Waldemar Wosiński

Answer from Atais works well. Below an upgrade to it.

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

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

and file META-INF/xyz-orm.xml with content:

<?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.xml then you can omit even first step because it is default confing for all persitence units.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!