我有一个名为Booking的模型,它有一个持久的DateTime字段。但是我不希望直接与此字段交互,而是通过两个Transient String字段, date 和 time 。问题是我不知道如何/何时将数据加载到字段中 - 它似乎没有使用我提供的构造函数,因为DateTime字段始终为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!
}
这是toDateTime方法:
private DateTime toDateTime(String date, String time){
DateTimeFormatter fmt = ISODateTimeFormat.dateHourMinute();
DateTime dt = fmt.parseDateTime(date+"T"+time);
return dt;
}
答案 0 :(得分:2)
也许你可以使用JPA的@PostLoad注释。这会导致在将持久数据加载到实体后调用带注释的方法。
更新:我提到了@PostLoad,但是@PrePersist可能是更好的选择,检查DateTime字段是否为空,如果是这种情况,您可以使用默认值设置它。就像这样:
@PrePersist
public void prePersist()
{
if(this.dateTime==null)
{
this.dateTime = toDateTime(this.date, this.time);
}
}
答案 1 :(得分:0)
我在上面的代码中假设DateTime是joda DateTime。我不认为JPA / Hibernate支持这种数据类型的持久性。支持的是时间戳,日历作为JDK的一部分提供。
您必须在Hibernate中定义新的用户类型才能使用DateTime。请检查此link
答案 2 :(得分:0)
看起来你可以定义一个默认构造函数,在JPA加载它时不需要参数来设置你的对象。像这样:
public Booking() {
DateTimeFormatter fmt = ISODateTimeFormat.dateHourMinute();
this.datetime = fmt.parseDateTime("1970-01-01T00:00");
}
现在唯一的问题是它使用了我从数据库中检索时定义的相同setter:* 引起:java.lang.IllegalArgumentException:格式无效:“ISO8601:2011-08-25T02:00 :00 + 0200 ......” *