How to persist an entity which contains a field of user type using JPA2
I'm looking for a way to persist an entity which contains a field of a user type. In this particular example I would like to 开发者_如何学Gopersist the ts field as number of milliseconds.
import org.joda.time.DateTime;
@Entity
public class Foo {
@Id
private Long id;
private DateTime ts;
}
JPA does not have the ability to register custom property types, you'll have to use provider specific stuff:
- Hibernate: http://joda-time.sourceforge.net/contrib/hibernate/
- EclipseLink: http://code.google.com/p/joda-time-eclipselink-integration/
OpenJPA: http://issues.apache.org/jira/browse/OPENJPA-473 (still open)
Since it's not a JPA defined supported type you rely on implementation specifics. DataNucleus has a plugin for JodaTime that would allow your desired persistence.
Either you can use those provider specific stuffs or you can make use of @PostPersist
, @PostUpdate
, @PostLoad
callback methods with a surrogate @Transient
field.
http://www.java2s.com/Tutorial/Java/0355__JPA/EntityListenerPostLoad.htm will give you some idea.
Please feel comfortable to get in touch for any further clarification.
One solution is to use non-column properties and encapsulate them with getters/setters.
To tell JPA to use getters/setters instead of directly accesing private fields, you must annotate @Id on public Long getId() instead of private Long id. When doing this, just remember to use @Transient for every getter that does not correspond directly to a column.
The following example would create a Date column named myDate, while the application would have DateTime getTs() and setTs() methods available for it. (not sure about DateTime API, so please forgive minor errors :))
import org.joda.time.DateTime;
@Entity
public class Foo {
private Long id;
private DateTime ts;
@Id
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
// These should be accessed only by JPA, not by your application;
// hence they are marked as protected
protected Date getMyDate() { return ts == null ? null : ts.toDate(); }
protected void setMyDate(Date myDate) {
ts = myDate == null ? null : new DateTime(myDate);
}
// These are to be used by your application, but not by JPA;
// hence the getter is transient (if it's not, JPA will
// try to create a column for it)
@Transient
public DateTime getTs() { return ts; }
public void setTs(DateTime ts) { this.ts = ts; }
}
精彩评论