JPA EntityManager详解(一)
EntityManager 详解

Java EE环境,包括EJB容器和Web容器。

(1)Web容器:只运行Web应用的容器,例如Tomcat就是开源的Web容器,它可以运行JSP、Servlet等。

(2)EJB容器:运行在EJB组件的容器,提供EJB组件的状态管理、事务管理、线程管理、远程数据资源访问、连接管理和安全性管理等系统级服务。例如JBoss为EJB容器和Web容器(Web容器是集成了Tomcat)结合。

部署在EJB容器中的JAR包都可以认为是运行在EJB容器中。但JBoss中的Web应用,比如war包中的类就不是运行在EJB容器中,而是运行在Web容器中。

J2SE环境

最普通Java运行环境,例如一个HelloWorld的Java程序就是运行在J2SE的环境中,通常使用main入口方法作为程序启动的触发。

如图11-1所示,它说明了Java EE与J2SE环境的关系。

两种类型的EntityManager对象

根据EntityManager对象的管理方式,可以有以下两种类型。

  • 容器托管的(container-managed)EntityManager对象

容器托管的EntityManager对象最简单,程序员不需要考虑EntityManager连接的释放,以及事务等复杂的问题,所有这些都交 给容器去管理。容器托管的EntityManager对象必须在EJB容器中运行,而不能在Web容器和J2SE的环境中运行。本书前面讲述的 EntityManager对象都是通过注入 @PersistenceContext注释来获得的,其实,这种获得EntityManager对象的方式就是容器托管的。

  • 应用托管的(application-managed)EntityManager对象

应用托管的EntityManager对象,程序员需要手动地控制它的释放和连接、手动地控制事务等。但这种获得应用托管的 EntityManager对象的方式,不仅可以在EJB容器中应用,也可以使 JPA脱离EJB容器,而与任何的Java环境集成,比如说Web容器、J2SE环境等。所以从某种角度上来说,这种方式是JPA能够独立于EJB环境运 行的基础。

理想状态下,最好是选用容器托管的EntityManager对象的方式,但在特殊的环境下,还是需要使用应用托管的EntityManager对象这种方式。

持久化上下文

持久化单元(persist unit)就是关于一组Entity的命名配置。持久化单元是一个静态概念。 


持久化上下文(Persist Context)就是一个受管的Entity实例的集合。每一个持久化上下文都关联一个持久化单元,持久化上下文不可能脱离持久化单元独立存在。持久化上下文是一个动态概念。 



尽管持久化上下文非常重要,但是开发者不直接与之打交道,持久化上下文在程序中是透明的,我们通过EntityManager间接管理它。 

三个类:Persistence,EntityManagerFactory和EntityManager

独立运行环境下:

EntityManagerFactory emf = Persistence.createEntityManagerFactory(“JPADemoPU”);

EntityManager entityManger = emf.createEntityManager();

使用容器的环境下,不需要通过Persistence创建EntityManagerFactory和EntityManger,而是通过注解实现

@PersistenceContext

private EntityManger entityManger;

@PersistenceUnit

private EntityMangerFactory emf;

容器管理的EntityManager

通过将@PersistContext注解标注在EntityManager类型的字段上,这样得到的EntityManager就是容器管理的EntityManager,我们不需要也不应该显式的关闭注入的EntityManager实例。 



容器管理的EntityManager细分为两种类型:事务类型和扩展类型。如果@PersistContext未指定type属性,或者指定为PersistContextType.TRANSACTION,则表示该类型是事务类型的,如果指定为PersistContextType.EXTENDED,表示该EntityManager是扩展类型的。 



事务类型:事务类型的EntityManger是无状态的,可用在无状态会话bean和有状态会话bean。事务类型的EntityManger依赖于JTA,每次调用EntityManager实例的方法时,EntityManager会查看是否某个持久化上下文与当前事务关联,如果有,则使用该持久化上下文,如果没有,EntityManager会创建一个持久化上下文,并将该持久化上下文与当前事务关联,事务结束时持久化上下文消失。 

JPA支持两种类型的事务:本地资源事务(RESOURCE_LOCAL)和JAVA事务API(JTA) 

本地资源事务(RESOUCE_LOCAL):使用JDBC驱动管理的本地事务。 

JAVA事务API(JTA):可用于管理分布式事务,管理多数据源的情况。 

容器管理的EntityManager总是使用JTA事务,应用程序管理的EntityManager可以使用本地资源事务,也可以使用JTA事务:在j2SE环境下默认是本地资源事务,在J2EE环境下,默认是JTA。事务的类型在persistence.xml中定义。 



扩展类型:扩展类型的EntityManager只能用于有状态会话Bean。扩展的EntityManager在有状态会话bean实例创建时候创建一个持久化上下文,直到该有状态会话bean销毁时,相应的持久化上下文才被移除。在扩展的EntityManager中,每次方法调用使用的都是相同的持久化上下文,所以前一次方法调用产生的受管实体下一个方法访问时仍然是受管实体。 
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐