Abstracted model interface in Play! ORM, how does initial-data.yml get loaded?
I have a model called Booking which has a persistent DateTime field. However I do not want to interact directly with this field, but rather through two Transient String fields, date and time. The problem is that I have no idea how/when play loads the data into the fields - it doesn't seem to be using the constructor I provide because the DateTime field is always null.
public class Booking extends Model {
@Column
@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
public DateTime datetime;
public Integer duration;
@Transient
public String date = "1970-01-01";
@Transient
public String time = "00:00";
public Booking(String date, String time, Integer duration) {
this.datetime = toDateTime(date, time);
this.duration = duration;
}
public void setDate(String dateStr) {
this.date = dateStr;
this.datetime = toDateTime(dateStr, this.time);
}
public void setTime(String timeStr) {
this.time = timeStr;
this.datetime = toDateTime(this.date, timeStr);
}
public String getDate() {
DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd");
return this.datetime.toString(format); //NullPointerException here!
}
public String getTime() {
DateTimeFormatter format = DateTimeFormat.forPattern("kk:mm");
return this.datetime.toString(format);//NullPointerException here!
}
here's t开发者_如何学运维he toDateTime method:
private DateTime toDateTime(String date, String time){
DateTimeFormatter fmt = ISODateTimeFormat.dateHourMinute();
DateTime dt = fmt.parseDateTime(date+"T"+time);
return dt;
}
JPA, which play uses, uses a default empty constructor to initiate the class. In your case the Play framework (I guess) creates a Booking() constructor. JPA then uses the getters and setters to set the properties of your entity.
Perhaps you could use the @PostLoad annotation from JPA. Which causes the annotated method to be called after your persistent data is loaded into the Entity.
Update: I mentioned @PostLoad, but perhaps the @PrePersist is an better option, to check if you DateTime field is null and if this is the case you could set it with your default value. Thus like so:
@PrePersist
public void prePersist()
{
if(this.dateTime==null)
{
this.dateTime = toDateTime(this.date, this.time);
}
}
I presume DateTime is joda DateTime in the above code. I don't think JPA/Hibernate supports this data type for persistence. The ones supported are Timestamp, Calendar available as part of JDK.
You have to define a new user type in Hibernate to work with DateTime. Check this link
It appears that you can define a default constructor that takes no parameters to set up your object when JPA loads it. Like so:
public Booking() {
DateTimeFormatter fmt = ISODateTimeFormat.dateHourMinute();
this.datetime = fmt.parseDateTime("1970-01-01T00:00");
}
Now the only problem is that it uses the same setters I've defined when retrieving from the database: *Caused by: java.lang.IllegalArgumentException: Invalid format: "ISO8601:2011-08-25T02:00:00+0200..." *
精彩评论