Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 一个实体管理器没有';看不到其他EntityManager完成的更新_Hibernate_Jpa - Fatal编程技术网

Hibernate 一个实体管理器没有';看不到其他EntityManager完成的更新

Hibernate 一个实体管理器没有';看不到其他EntityManager完成的更新,hibernate,jpa,Hibernate,Jpa,我在独立应用程序中使用了两个EntityManager实例,其资源为本地事务类型。我执行以下操作: 使用第一个EntityManager(em1)保存实体 使用第二个EntityManager(em2)更新实体 使用第一个EntityManager(em1)读取实体 问题是第三步的em1没有看到em2完成的更新 EntityManagerFactory emf = Persistence.createEntityManagerFactory("test"); // Step 1: crea

我在独立应用程序中使用了两个EntityManager实例,其资源为本地事务类型。我执行以下操作:

  • 使用第一个EntityManager(em1)保存实体
  • 使用第二个EntityManager(em2)更新实体
  • 使用第一个EntityManager(em1)读取实体
问题是第三步的em1没有看到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读取陈旧数据吗?

如果实体的引用在请求数据库之前存在,则
EntityManager
首先在其一级缓存中查找。
em1
变量引用的
EntityManager
实例在缓存中保留了id为
1
Article
实体。
因此,此语句将从缓存中检索实体:

Article updatedArticle = em1.find(Article.class, 1L);
要防止这种行为,有多种方法:

  • 通过调用
    EntityManager.detach()
    将实体从EntityManager上下文中分离
  • 通过调用
    EntityManager.refresh()
    ,从数据库中刷新实体的状态。在这种情况下,不再需要
    find()
    查询
  • 更激进的做法是:通过调用:
    EntityManager.clear()

EntityManger 1拥有自己的文章对象缓存版本

在由it管理之前,它将为您提供旧版本。如果您想这样做,两个不同的实体经理应该使用刷新而不是查找

em1.refresh(article);
关于一级缓存:


关于刷新

可能会出现许多原因。。。您是否尝试
flush()
execute()
cahce?所描述的行为通常是已知且正确的。如果是应用程序管理的EntityManager,则为每个事务创建一个新的EntityManager是否是一个好主意?
EntityManager
的工作方式是:一个事务一个事务。在阅读代码时,我想知道的问题是,为什么要创建这么多事务?可以将事务同化为客户端请求。如果您有3个不同的请求,那么可以创建3个EntityManager。但这是您的用例吗?基本上,我想测试悲观锁定是如何工作的。这意味着我需要在并发事务中运行读/写操作(即在不同的线程中)。在编写测试时,我观察到EntityManager读取了过时的数据,但不明白为什么。因此,我编写了一个没有线程和锁的简化示例。在本例中,使用多个EM的示例代码就可以了。