我需要知道在保存之前是否已更改模型对象的某些字段,因为我需要将新值与旧值进行比较。
我无法触摸它们生成的模型类。
我的问题是,每当我更改控制器中的对象并检查数据库是否存储该对象时,在保存修改后的对象之前,数据库中返回的对象与修改后的对象“相同”。 / p>
我正在玩Play! 1.2.7基本上我有这个:
class MyModel extends Model {
public String label;
}
class MyModels extends Controller {
public static void save(Long id) {
MyModel m = MyModel.findById(id); // at this point m.label is "original"
m.label = "changed !";
MyModel m2 = MyModel.findById(id); // m2.label is "changed !" but should be "original", shouldn't it ?
}
}
也许问题可能是:如何强制JPA EntityManager查看数据库是否真实而不是从上下文返回对象?因为这似乎是真正的问题。
解决方案
所以最终的解决方案是:
class MyModels extends Controller {
public static void save(Long id) {
MyModel m = MyModel.findById(id); // at this point m.label is "original"
m.label = "changed !";
MyModel m2;
JPAPlugin.startTx(false);
try {
m2 = MyModel.findById(id); m2.label is "original"
} finally {
JPAPlugin.closeTx(false);
}
}
}
另一种实现此目的的方法是创建一个新的EntityManager,如下所示:
EntityManager manager = JPA.entityManagerFactory.createEntityManager();
// set your new EntityManager as you like...
manager.setProperty("org.hibernate.readOnly", true);
Query q = manager.createQuery("select m from MyModel m where id = :id");
q.setMaxResults(1);
q.setParameter("id", m.getBaseId());
MyModel m2 = (MyModel) q.getResultList().get(0);
答案 0 :(得分:0)
您可以向模型添加布尔字段(例如“hasBeenModified” - 使用false初始化),而不将其绑定到数据库,每当更新对象时,将hasBeenModified的值更改为true。
答案 1 :(得分:0)
您可以在Entity / Table中添加一个版本字段,就像它用于jpa中的乐观锁定一样。
答案 2 :(得分:0)
要强制Hibernate在playframework中启动一个新事务,从而为你提供一个新的实体管理器,它将返回数据库中的对象,而不是对它的引用,你需要特别要求play框架启动通过JPAPlugin进行的新交易。
JPAPlugin.startTx(false);
try {
// your code
} finally {
JPAPlugin.closeTx(false);
}
的javadoc
答案 3 :(得分:0)
看起来你正在使用扩展会话/ entityManager。你什么时候开会? 你试过了吗?
session.clear()/entityManager.clear()
在第二次调用MyModel.findById(id)之前; ?
class MyModels extends Controller {
public static void save(Long id) {
MyModel m = MyModel.findById(id); // at this point m.label is "original"
m.label = "changed !";
MyModel.clear() // I don't know if you have a MyModel.clear() but you should call session.clear()/entityManager.clear() here
MyModel m2 = MyModel.findById(id);
}
}