一个EntityManager看不到另一个EntityManager完成的更新 [英] One EntityManager doesn't see updates done by another EntityManager

查看:91
本文介绍了一个EntityManager看不到另一个EntityManager完成的更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在具有RESOURCE_LOCAL事务类型的独立应用程序中使用两个EntityManager实例.我执行这样的操作:

I'm using two EntityManager instances in standalone application with RESOURCE_LOCAL transaction type. I perform such operations:

  • 使用第一个EntityManager(em1)保存实体
  • 使用第二个EntityManager(em2)更新实体
  • 使用第一个EntityManager(em1)读取实体

问题在于,第3步上的em1看不到em2完成的更新.

The problem is that em1 on the 3rd step doesn't see updates done by em2.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");

// Step 1: create entity
EntityManager em1 = emf.createEntityManager();
em1.getTransaction().begin();
Article article = new Article("article_1");
em1.persist(article);
em1.getTransaction().commit();

// Step 2: update entity
EntityManager em2 = emf.createEntityManager();
em2.getTransaction().begin();
Article articleForUpdate = em2.find(Article.class, 1L);
articleForUpdate.setName("updated article_1");
em2.persist(articleForUpdate);
em2.getTransaction().commit();

// Step 3: read updated entity
em1.getTransaction().begin();
Article updatedArticle = em1.find(Article.class, 1L);
em1.getTransaction().commit();

log.info("updated entity: {}", updatedArticle); // logs stale data

em1.close();
em2.close();
emf.close();

有人可以解释为什么em1读取过时的数据吗?

Can anyone explain why em1 reads stale data?

推荐答案

如果在请求数据库之前存在对实体的引用,则EntityManager首先在其一级缓存中查找.
em1变量引用的EntityManager实例在其缓存中具有ID为1Article实体,因为它已将其持久化. 因此,该语句将从缓存中检索实体:

The EntityManager looks first in its first level cache if a reference of the entity exists before requesting the database.
The EntityManager instance referenced by the em1 variable has the Article entity with the id 1 in cache as it has persisted it.
So this statement will retrieve the entity from the cache :

Article updatedArticle = em1.find(Article.class, 1L);

要防止此行为,您可以采用多种方式:

To prevent this behavior you have multiple ways :

  • 通过调用EntityManager.detach()将实体与EntityManager上下文分离.
  • 通过调用EntityManager.refresh()从数据库刷新实体的状态.在这种情况下,不再需要find()查询.
  • 更多基本方法:通过调用EntityManager.clear()
  • 清除EntityManager上下文
  • detach the entity from the EntityManager context by invoking EntityManager.detach().
  • refresh the state of the entity from the database,by invoking EntityManager.refresh(). In this case, the the find() query is not any longer required.
  • more radical : clear the EntityManager context by invoking : EntityManager.clear()

这篇关于一个EntityManager看不到另一个EntityManager完成的更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆