1

试图找出一些可能的情况,什么时候 aEntityManagerFactory在 EJB 中可能有用。当然,通常只需要一个事务范围EntityManager(JTA 范围),以便所有注入的 EntityManager 共享相同的PersistenceContext. 在以下情况下会发生什么:

  1. 何时@PersistenceContext(type=PersistenceContextType.EXTENDED)使用:此 JTA 是否启用?这种 EntityManager 的请求会在 JTA 的上下文中执行吗?如果不是,那在哪一个?(注意:当然它只适用于@StatefulEJB)。当然很清楚,在这种情况下,EntityManager 将拥有自己的/特殊的 PersistenceContext。

  2. 当一个人用于在 EJB@PersistenceUnit中获取 aEntityManagerFactory时(我想它适用于所有类型的 EJB,对吗?),获得的EntitymanagerJTA 是否启用(当然Entitymanager.joinTransaction()是必要的)?如何从工厂获得事务范围(启用 JTA)或扩展实体管理器?何时使用工厂而不是实体管理器有用。(当然,很明显 EntityManagerFactory 是 Java SE 应用程序到 JPA 的唯一接口,但是 EJB 呢?)。

4

1 回答 1

2

您的问题围绕着假设您处于一种情况,即您必须注入 @PersistenceUnit 以在 EJB 中获取 EntityManagerFactory。好吧......让我在这里叙述一些缺失的背景:

在 servlet 中

我们必须按照以下步骤来实例化 EntityManager:

  1. 注入 @PersistenceUnit 以获取 EntityManagerFactory
  2. 使用这条线: entityManager = entityManagerFactory.createEntityManager();

上述 2 个步骤保证 EntityManager 是当前线程的本地,因此是线程安全的。这种情况是 servlet 在容器注入方面可重入的一种解决方法。这意味着 servlet 将接受由容器注入的已经存在的 entityManager。

在 EJB 中

根据定义,EJB 在容器注入方面是不可重入的,因此我们知道容器将为 EJB 实例化一个新的本地实体管理器代理,因此是线程安全的。

也就是说,我们可以讨论如何/何时使用 Extended PersistenceContext

引用 JPA 规范第 294 页的 JSR-317:

容器管理的扩展持久性上下文只能在有状态会话 bean 的范围内启动。它从创建声明依赖于 PersistenceContextType.EXTENDED 类型的实体管理器的有状态会话 bean 开始存在,并且据说绑定到有状态会话 bean... 当容器关闭持久性上下文时有状态会话 bean 的 @Remove 方法完成(否则有状态会话 bean 实例被破坏)。

因此,可以使用属性 PersistenceContextType.EXTENDED 破坏不可重入功能,仅用于服务有状态会话 bean 语义。只要有状态会话 bean 存在,它就必须维护完全相同的 EntityManager。

总结

在你的第一个问题中:

EntityManagerFactory 什么时候在 EJB 中有用?

答案是:没用。

至于你的第二个问题,我相信第一个答案和上面的背景叙述首先不需要问它!

于 2012-11-21T02:16:26.723 回答