Hibernate.org社区文档

第一章 架构

1.1. 定义
1.2. 在容器环境中(例如 EJB 3)
1.2.1. 容器管理的实体管理器
1.2.2. 应用程序管理的实体管理器
1.2.3. 持久性上下文范围
1.2.4. 持久性上下文传播
1.3. Java SE 环境

JPA 2 是 Java EE 6.0 平台的一部分。在容器如 EJB 3 或更现代化的 CDI(Java Context and Dependency Injection,Java 上下文和依赖注入)中,以及在特定容器外部执行的独立 Java SE 应用程序中,都可以使用 JPA 中的持久性。以下编程接口和构件在两种环境中皆可用。

实体管理器是与持久化上下文进行交互的 API。可以使用两种常见的策略:将持久化上下文绑定到事务边界,或者保持持久化上下文在多个事务中可用。

最常见的情况是将持久化上下文范围绑定到当前事务范围。只有在使用 JTA 事务时才能这样做:持久化上下文与 JTA 事务生命周期相关联。当调用一个实体管理器时,如果当前 JTA 事务没有关联的持久化上下文,也会打开持久化上下文。否则,将使用关联的持久化上下文。当 JTA 事务完成时,持久化上下文也会结束。这意味着在 JTA 事务期间,应用程序将能够处理同一持久化上下文的托管实体。换句话说,您不必在托管 bean (CDI) 或 EJB 方法调用中传递实体管理器的持久化上下文,而只需在需要实体管理器时使用依赖项注入或查找即可。

您还可以使用扩展持久化上下文。如果您使用容器管理实体管理器,这可以与有状态会话 bean 结合使用:在从依赖项注入或 JNDI 查找中检索实体管理器时创建持久化上下文,并在容器在完成 Remove 有状态会话 bean 方法后关闭它之前一直保留。这是一个实现“长时间”工作模式的完美机制。例如,如果您必须将多个用户交互周期作为一个工作单元来处理(例如,必须完全完成的向导对话框),您通常会从应用程序用户的角度将此建模为一个工作单元,并使用扩展持久化上下文来实现它。有关此模式的更多信息,请参阅 Hibernate 参考手册或《实用 Hibernate》一书。

JBoss Seam 3 建立在 CDI 的基础上,其核心概念是会话和工作单元的概念。对于应用程序管理的实体管理器,在创建实体管理器时创建持久性上下文,并在关闭实体管理器时保留该持久性上下文。在扩展持久性上下文中,在事务外执行的所有修改操作(持久、合并、删除)都会排队,直到持久性上下文附加到事务中。该事务通常在用户进程结束时发生,以便可以提交或回滚整个进程。对于应用程序管理的实体管理器,仅支持扩展持久性上下文。

EntityManagerFactory.createEntityManager()(应用程序管理)创建的资源本地实体管理器或实体管理器与持久性上下文之间为一对一关系。在其他情况下会出现 持久性上下文传播

持久性上下文传播会出现在容器管理的实体管理器中。

在事务范围的容器管理实体管理器中(Java EE 环境中的常见情况),JTA 事务传播与持久性上下文资源传播相同。换句话说,在给定的 JTA 事务中检索到的容器管理的事务范围的实体管理器都共享相同的持久性上下文。按照 Hibernate 条款,这意味着所有管理者都共享相同的会话。

重要提示:持久性上下文绝不会在不同的 JTA 事务之间或不属于同一实体管理器工厂的实体管理器之间共享。在使用扩展持久性上下文时,上下文传播有一些值得注意的例外

在 Java SE 环境中,只有受应用管理的扩展上下文实体管理器可用。您可以使用 EntityManagerFactory API 检索实体管理器。只有资源本地实体管理器可用。换句话说,Java SE 中不支持 JTA 事务和持久性上下文传播(您必须自己传播持久性上下文,例如使用 Hibernate 社区流行的线程本地会话模式)。

扩展上下文意味着在检索实体管理器(使用 EntityManagerFactory.createEntityManager(...) )时创建一个持久性上下文,并在关闭实体管理器时将其关闭。在这种情况下,许多资源本地事务共享同一个持久性上下文。