Play中的抽象模型界面! ORM,initial-data.yml是如何加载的?

时间:2011-09-12 12:26:53

标签: java design-patterns orm persistence playframework

我有一个名为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;
  }

3 个答案:

答案 0 :(得分:2)

播放使用的JPA使用默认的空构造函数来启动该类。在你的情况下,Play框架(我猜)创建一个Booking()构造函数。然后,JPA使用getter和setter来设置实体的属性。

也许你可以使用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 ......” *