Play框架:实现restful更新操作的问题

时间:2013-10-02 20:46:58

标签: rest playframework playframework-2.1 h2 ebean

我们正在创建基于Play framework 2.1.x的RESTFul API,它以JSON格式传输/接受数据。 创建阅读删除操作很容易实现,但我们已经遇到了更新操作。

以下是我们拥有的实体:

事件:

@Entity
public class Event extends Model {

   @Id
   public Long id;

   @NotEmpty
   public String title;

   @OneToOne(cascade = CascadeType.ALL)
   public Location location;

   @OneToMany(cascade = CascadeType.ALL)
   public List<Stage> stages = new LinkedList<Stage>();

   ...
}

位置:

@Entity
public class Location extends Model {

   @Id
   public Long id;

   @NotEmpty
   public String title;

   public String address;

   ...
}

阶段:

@Entity
public class Stage extends Model {

    @Id
    public Long id;

    @NotEmpty
    public String title;

    public int capacity;

    ...
}

在我们的路由器中,我们有以下条目:

PUT  /events/:id controllers.Event.updateEvent(id: Long)
控制器中的

updateEvent 方法遵循以下方式(注意:我们使用Jackson库将对象映射到JSON并返回):

@BodyParser.Of(BodyParser.Json.class)
public static Result updateEvent(Long id) {
    Event event = Event.find.byId(id);

    Http.RequestBody requestBody = request().body();
    JsonNode jsonNode = requestBody.asJson();

    try {
        ObjectMapper mapper = new ObjectMapper();
        ObjectReader reader = mapper.readerForUpdating(event);

        event = reader.readValue(jsonNode);
        event.save();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return ok();
}

在我们从数据库获得事件后,通过使用ObjectReader从JSON读取更新其值,我们尝试保存更新的事件并获得异常(类似于我们在尝试更新阶段列表时得到的):

org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_9F ON PUBLIC.LOCATION(ID)"; SQL statement: insert into location (id, title, address) values (?,?,?) [23505-168]

根据H2日志框架尝试对位置执行插入操作并失败,因为已存在具有指定id的位置。当我们从DB获取Event时,我们已经调查了更多的ant,因为懒惰的提取而没有加入位置。看起来问题是保存我们的事件与之关系的其他实体。我们尝试通过执行以下操作来强制获取位置操作:

Event event = Ebean.find(Event.class).fetch("location").where().eq("id", id).findUnique();

但是当我们使用ObjectReader的readValue方法更新此事件并保存Event时,我们会得到相同的异常。

我们还尝试从JSON创建单独的Event对象,并逐个字段地从DB更新Event(由我们自己实现合并操作)并且它有效但看起来很奇怪框架不提供任何合并和更新实体的方法从客户端传递数据。

有人可以就如何解决这个问题提出建议吗?任何显示如何实现实体与来自客户端的JSON数据合并并在存储中更新它的示例都将受到高度赞赏。

1 个答案:

答案 0 :(得分:0)

您现在可能已经修复了错误,但是如果这有助于其他人,我还是会回复它。

我只是Play Framework的初学者,也是几天前才开始的。但是我相信当你的代码进入时:

event.save();

你应该这样做:

event.update();

这里的问题是你没有在数据库中插入新实体,但实际上只是更新已存在的实体,所以你需要使用第二种方法。

您可以在http://www.playframework.com/documentation/2.0/api/java/play/db/ebean/Model.html

找到有关此内容的更多信息