JPA EntityManager 持久化上下文 (Persistence Context ) 一个持久化单元 (Persistence Unit ) 就是关于一组Entity 类的命名配置。持久化单元是一个静态的概念。
一个持久化上下文 (Persistence Context ) 就是一个受管的Entity 实例的集合。每一个持久化上下文都关联一个持久化单元,持久化上下文不可能脱离持久化单元独立存在。持久化上下文中的Entity 实例就是相关联的持久化单元中的若干Entity 的实例。持久化上下文是一个动态的概念。
一个Entity 实例处于受管状态,其实质是: 该实例存在于某个持久化上下文中,并且可能被某个EntityManager 处理,也因为这个原因,所以我们说一个EntityManager 管理一个持久化上下文。
尽管持久化上下文非常重要,但是开发者不直接与之打交道,持久化上下文在应用程序中是透明的,我们需要通过EntityManager 间接管理它。
容器管理的EntityManager(Container-Managed EntityManager) 通过将@PersistenceContext 注解标注在EntityManager 类型的字段上,这样得到的EntityManager 就是容器管理的EntityManager 。由于是容器管理的,所以我们不需要也不应该显式关闭注入的EntityManager 实例。
容器管理的EntityManager 又细分为两种类型: 事务范围 (Transaction ) 的和扩展的 (Extended ) 。
若@PersistenceContext 未指定type 属性,或者指定为PersistenContextType.TRANSACTION ,则表示该EntityManager 是事务范围的;若指定为PersistenContextType.EXTENDED 的,则表示该EntityManager 是扩展的。
事务范围: 事务范围的EntityManager 是无状态的,可用在无状态会话Bean 和有状态会话Bean 中。
事务范围的EntityManager 依赖于JTA 事务,每次调用EntityManager 实例的相关方法时,EntityManager 会查看是否有某个持久化上下文与当前事务关联,如果有,则使用该持久化上下文;如果没有,则EntityManager 将创建一个持久化上下文,并将该持久化上下文与当前事务关联。当事务结束,则持久化上下文消失。
扩展的: 扩展的EntityManager 只能用于有状态会话Bean 。
扩展的EntityManager 在有状态会话Bean 实例创建的时候创建一个持久化上下文,并且直到该有状态会话Bean 销毁,则相应的持久化上下文才被移除。
由于在扩展的EntityManager 中,每次方法调用都是使用的相同的持久化上下文,所以前一次方法调用时产生的受管实体在下一个方法访问时仍然为受管实体。
...