3

我正在使用 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)

我想我可以通过驱逐从 PersistenceContext / 缓存中删除实体。

如何实现拥有两个不同的实体:a)更改的实体和 b)步骤 3 中加载的数据库中的原始实体)

并且:如果我 refresh() 实体,我希望 find 方法返回刷新的实体。那是对的吗?

我也尝试了 @PreUpdate 侦听器,结果相同,所以我认为关于 JPA PersistenceContext 或 Java 引用一定有一些我不理解的东西......

我希望我提供了足够的信息!提前致谢!

4

3 回答 3

3

为了更好地了解 JPA 生命周期,我发现这个站点(尤其是状态图)很有帮助:http ://www.objectdb.com/java/jpa/persistence/managed

主要的收获是,当您从持久性上下文中删除对象时,它们不会“消失”。您obj仍将指向完全初始化MyObjectname设置为“新名称”。唯一的区别是提交事务/刷新持久化上下文将不再更新相应的数据库条目。

当您想obj在提交到数据库之前查看更改时,您有多种选择。如果快速和肮脏就足够了,我建议

MyObject original = obj.clone();

objoriginal您喜欢的任何工具(或仅将两者都打印到您的日志)进行比较。

关于refresh(),请查看此页面的内容:

内存中托管对象的内容被丢弃(包括更改,如果有的话)并被从数据库中检索到的数据替换。这对于确保应用程序处理实体对象的最新版本可能很有用,以防万一它在检索后可能已被另一个 EntityManager 更改。

于 2013-08-01T13:18:01.733 回答
2

如果你像我一样使用 Spring @Transactional。您可以执行以下操作:

@Transactional
MyEntityObject update(MyEntityObject myEntityObject){
   boolean isNameChanged;
   em.detach(myEntityObject);
   MyEntityObject inDBObject = em.load(myEntityObject.getId());
   isNameChanged = (myEntityObject.getName() != inDBObject.getName());
} 
于 2015-12-17T16:42:57.180 回答
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();

祝一切顺利!

于 2013-08-01T13:15:21.810 回答