Project正在使用play framework 1.3.3 我有一个这样的控制器:
public static void save(Item item) {
if (item.id != null) { //It means that item is not new, it is being edited
Item existingOldItem = Item.findById(item.id);
//Here I should have an old version of an item as "existingOldItem"
//and new one coming from http request as "item"
}
但问题是item和existingOldItem非常相同。 Item.findById行没有从数据库返回一个旧项,但是从http请求返回新项(与JPA.em()。createQuery相同)。我想play框架在缓存中发送一个新项目,findById从缓存中返回该项目,而不是从数据库中返回。请有人向我解释其背后的逻辑以及如何解决问题的方法。
答案 0 :(得分:3)
问题是item和existingOldItem非常相同。 Item.findById行不会返回数据库中的旧项目
这是预期的行为。 Item.findById()返回由HTTP客户端修改的旧项。从Play中看JPA object binding!文档以查看调用模式。
拜托,有人可以解释一下它背后的逻辑......
简而言之,HTTP客户端应该在HTTP请求中提供项记录的ID及其新属性值。玩!设置Folder
参数准备保存,在数据库中查找项目并根据POST参数修改其属性。所以你不应该有一个“旧”和“新”的项目,你应该有一个
“item”对象可能是旧的还是新的,具体取决于是否找到了HTTP客户端提供的ID
在数据库中。您的所有控制器操作都必须调用item
。
魔法在item.save()
。正如您猜测的那样,它首先在数据库中查找对象。
如果找到该对象,则使用该对象调用JPAPlugin.bind
。这也是神奇的
default实现设置Item的所有属性,其中有匹配的HTTP参数。
......以及如何解决问题的方法。
我不确定你认为问题是什么,但如果你想要一个旧的和一个新的项目,那么客户不应该提供
Item.edit()
参数。如果你不喜欢那个Play!深入了解您的数据库以实例化item.id
参数,然后您可以提供自定义
binder或让控制器动作接受类似外观的POJO类,而不是JPA类。