db更新前的计算

时间:2011-09-16 16:12:45

标签: jpa playframework

我正在使用Play Framework,我认为这是一个非常频繁的持久性问题:

  • 我显示一个表格,其中包含来自数据库的值和一个字段'quantity'
  • 用户更新表单并更改“数量”值
  • 他点击了“保存按钮”
  • 在调用的控制器方法中,我想获取“数量”的旧值并在更新数据库之前计算新旧值之间的差异
  • 为了做到这一点,我使用了findById(在调用object.save方法之前),但是它给了我新的值,而不是旧值:它显然会查找一些缓存(哪一个?)而不是请求DB < / LI>

=&GT;那是正常的吗?我如何获得旧值,进行计算然后坚持?

非常感谢您的帮助,我不想在我的数据库中管理旧/新值...我确定这是不好的做法!

更新

    public static void save(@Valid Lot lot) {
     History element = new History();
     element.date = new Date();
     //HERE below it returns the new value, not the old one
     Lot databaseLot = Lot.findById(lot.id); 
     element.delta= databaseLot.quantity - lot.quantity;
     element.save();
     lot.save();
     list(null, null, null, null);
}

3 个答案:

答案 0 :(得分:3)

这是因为,Play在这里为你做了一些魔术。

当您将JPA对象传递到包含ID的控制器时,Play将自动从数据库中检索此JPA对象。如果你look here,它会更详细地解释这一点。它声明(并假设传递用户JPA Pojo的动作调用)

  

您可以使用HTTP自动绑定JPA对象到Java   结合。

     

您可以在HTTP参数中自己提供user.id字段。   当Play找到id字段时,它会从中加载匹配的实例   数据库在编辑之前。 HTTP提供的其他参数   然后应用请求。所以你可以直接保存它。

那么,你怎么解决这个问题呢?我想最简单的方法是不将id作为Pojo对象的一部分传递,并将ID作为单独的参数传递,因此Play将认为不需要从数据库中自动检索该对象。

另一种方法是使用数量字段的setter方法来更新delta。因此,Play将自动从数据库中检索对象,然后调用setter方法更新值(按照正常的POJO绑定),并作为该操作的一部分,设置新数量和增量。完善!在我看来,这是最好的选择,因为它还可以确保业务逻辑整齐地保留在模型中,而不是控制器中。

答案 1 :(得分:0)

我无法专门与Play Framework交流,但在JPA中,EntityManager缓存对象的生命周期,除非明确清空。因此,查询上下文已经管理的对象只会为您提供缓存版本。此外,听起来你所获得的EM被声明为EXTENDED,这导致在多个请求中使用相同的EM(或者框架可以在封面下进行查找并在处理之前设置值它)。

您需要解决此缓存问题或将Play配置为使用TRANSACTION范围的持久性上下文(又称EntityManager)。我无法帮助你,但前者很容易。

int newQuantity = entity.getQuantity();
entityManager.refresh(entity);
// enity.getQuantity() should now give you the old value
// Do your calculation
// entity.setQuantity(newQuantity);

在交易结束时,您的新状态应该保存。

答案 2 :(得分:0)

您可以将数量值保存在隐藏文本中,然后可以处理