我正在使用OpenJPA 2.2.1,并希望执行以下操作:
1)加载实体 2)更改实体 3)检查保存实体之前完成的更改
我做了什么:
1)通过
加载实体 EntityManager.find(MyObject.class, id);
2)好的,很清楚,我认为,像
MyObject obj = EntityManager.find(MyObject.class, id);
obj.setName("New name");
3)试图从PersistenceContext中逐出对象并通过以下方式从数据库中再次加载:
EntityManager.evict(MyObject.class, id);
EntityManager.find(MyObject.class, id);
3)中的find()调用返回的实体总是与1)中找到的实体相等(等于ID)
我以为我可以通过evict从PersistenceContext / cache中删除实体。
如何实现两个不同的实体: a)变更的实体和 b)步骤3)中加载的数据库中的原始实体
并且:如果我刷新()实体,我希望find方法返回刷新的实体。这是对的吗?
我也尝试了@PreUpdate监听器,结果相同,所以我认为必须有一些我对JPA PersistenceContext或Java引用不了解的东西......
我希望我提供了足够的信息!提前谢谢!
答案 0 :(得分:3)
为了更好地了解JPA生命周期,我发现这个站点(特别是状态图)很有帮助:http://www.objectdb.com/java/jpa/persistence/managed
主要的一点是,当您从持久化上下文中删除它们时,对象不会“消失”。您的obj
仍会指向已完全初始化的MyObject
,其中name
设置为“新名称”。唯一的区别是提交事务/刷新持久化上下文将不再更新相应的数据库条目。
如果要在提交数据库之前查看对obj
的更改,可以使用多个选项。如果快速和肮脏就够了,我建议
MyObject original = obj.clone();
并将obj
和original
与您喜欢的任何工具(或只是简单地打印到日志中)进行比较。
关于refresh()
,请查看this page所说的内容:
内存中托管对象的内容将被丢弃(包括更改,如果有),并替换为从数据库中检索的数据。这可能有助于确保应用程序处理实体对象的最新版本,以防它被检索后可能已被另一个EntityManager更改。
答案 1 :(得分:2)
如果你像我一样使用Spring @Transactional。您可以执行以下操作:
@Transactional
MyEntityObject update(MyEntityObject myEntityObject){
boolean isNameChanged;
em.detach(myEntityObject);
MyEntityObject inDBObject = em.load(myEntityObject.getId());
isNameChanged = (myEntityObject.getName() != inDBObject.getName());
}
答案 2 :(得分:0)
怎么样:
1 /读取(或找到)对象到内存[这就是你所做的]
2 /从商店中取出物品;类似的东西:
em.getTransaction().begin();
em.remove(obj);
em.getTransaction().commit();
3 /对内存中的对象进行任何更新;
obj.setName("My New Name");
4 /最后坚持更新的对象:
em.getTransaction().begin();
em.persist(obj);
em.getTransaction().commit();
以上代码段基于javax.persistence.*;
包,em
是一个如此定义的实例:
EntityManagerFactory emFactory = Persistence.createEntityManagerFactory(PERSISTENT_UNIT);
EntityManager em = emFactory.createEntityManager();
一切顺利!