Ebean覆盖保存,更新方法不会通过级联保存,更新来调用

时间:2013-05-06 19:15:04

标签: playframework playframework-2.0 ebean

我有一个基类:

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Version;

import play.db.ebean.Model;

@MappedSuperclass
public class TimeStampable extends Model {

    @Id
    @GeneratedValue
    public Long id;

    @Column(name = "created_at")
    public Date createdAt;

    @Column(name = "updated_at")
    public Date updatedAt;

    @Version
    public int version;

    @Override
    public void save() {
        if (this.id == null) {
            createdAt();
        } else {
            updatedAt();
        }
        super.save();
    }

    @Override
    public void update() {
        updatedAt();
        super.update();
    }

    @Override
    public void update(Object o) {
        updatedAt();
        super.update(o);
    }

    @PrePersist
    void createdAt() {
        this.createdAt = this.updatedAt = new Date();
    }

    @PreUpdate
    void updatedAt() {
        this.updatedAt = new Date();
    }
}

和2个模特

public class Request extents TimeStampable {
     @OneToMany(cascade = CascadeType.ALL)
     public List<Response> responses = new ArrayList<Response>();
}

public class Response extents TimeStampable {
}

当我尝试保存Request对象时,我看到我的DB已经为Request对象正确填充了created_at updated_at字段,但对于Response对象,这些值为null。响应对象的其他字段具有预期值(我已填写)。

以下是我保存请求的方式。

Request req = new Request();
Response res = new Response();
// code to populate response fields

request.add(res);
Ebean.save(req);

我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

似乎@PrePersist@PreUpdate没有使用您提供的逻辑调用。使用save()方法手动调用时执行这些操作。我找到了两个解决你问题的方法。

首先,因为您使用单向 OneToMany关系(Response对象可能不知道与其关联的Request对象,因为没有类型的字段Request对象上的Response,在save()对象保存之前,不允许在Response对象上调用Request方法。

如果您坚持使用此关系类型。在TimeStampable模型上,在createdAtupdatedAt字段中添加这些注释:

@Column(name = "created_at")
@CreatedTimestamp
public Date createdAt;

@Column(name = "updated_at")
@UpdatedTimestamp
public Date updatedAt;

这两个注释是eBean注释。

第二种选择是,您可以在ResponseRequest类之间使用双向关系。在Response类上添加字段以引用Request对象。

public class Response extends Timestampable {
    @ManyToOne // to make relation bidirectional
    public Request request;
}

TimeStamp超类上,您可以删除 @UpdatedTimestamp@CreatedTimestamp注释,因为您可以在控制器上调用save()方法。以下是使用此方法在控制器上填充数据的示例:

// create new request object and save
Request request = new Request();
request.save();

// populate the response
Response response1 = new Response();
response.request = request;
Response response2 = new Response();
response.request = request;
response.save();
response.save();

  

建议

     

我建议您使用第二种方法,因为如果您有Response个对象,您将知道与其关联的Request对象。