持久化上下文(Persistence Context)
(什么时候公用一个持久化上下文,和entitymanager,和entitymanagerFactory比较说明)
一个持久化单元(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中,每次方法调用都是使用的相同的持久化上下文,所以前一次方法调用时产生的受管实体在下一个方法访问时仍然为受管实体。
应用程序管理的EntityManager(Application-ManagedEntityManager)
在JavaSE和JavaEE环境下创建应用程序管理的EntityManager的不同之处,并非创建EntityManager的方式不同,而是获得创建EntityManager的EntityManagerFactory的方式不同。
JavaSE环境:Persistence.createEntityManager(“APU”).createEntityManager();
JavaEE环境:使用@PersistenceUnit(unitName=”APU”)标注EntityManagerFactory属性。然后通过调用emf.createEntityManager()获得EntityManager。由于EntityManager是开发者显式创建并管理的,因此需要在用完之后调用em.close()方法将之关闭。EntityManagerFactory是容器注入的,不需要也不应该调用emf.close()方法。
在JavaSE环境下,Persistence类有两个重载的createEntityManagerFactory()方法:
有一个参数:该参数表示PersistenceUnit的名字,然后使用persistence.xml中的属性创建一个EntityManagerFactory。
有两个参数:第一个参数的作用同上,第二个参数可以让开发者设置额外的一些属性,可以作为persistence.xml中属性的扩充,如果属性的键与persistence.xml中相同,则代码中的设置覆盖persistence.xml中的配置值。
就持久化上下文而言,应用程序管理的EntityManager就像扩展的容器管理的EntityManager。当创建应用程序管理的EntityManager实例之后,该EntityManager实例立即创建一个属于它自己私有的持久化上下文,该持久化上下文将一直存活下去,直到所属的EntityManager实例销毁才消失。