内容来源于阅读 JPA 2.0 规范、 Apache OpenJPA 相关文档、 Seam in Action 后的总结。
1. 四大要素 :
2. 四大要素关系用图表示如下:
Persistence : 包含创建 EntityManagerFactory 的静态方法及整个 persistence.xml 配置文件信息。
EntityManagerFactory : 由 Persistence 创建,对应 Persistence 中的一个 unit 。其创建过程比较费资源,一般整个应用程序只创建一次。 EntityManagerFactory 的主要职责是创建 EntityManager 。
EntityManager :由 EntityManagerFactory 编程创建或由容器创建,在容器外使用时会对应一个 EntityTraction ( em.getTransaction )。与 PersistenceContext 的对应关系看 PC 部分。 EntityManager 的职责包括: Transaction association , Entity lifecycle management (实质上 PC 管理), Entity identity management (实质上 PC 管理), Cache management (实质上 PC 管理), Query factory , Closing( 释放资源 ) 。 EntityManager 生命周期:如果是 container-managed ,则由容器控制,如果是 applaction-managed 则由应用程序控制(所有 j2se 和某些特殊的 javaee 环境中)。
PersistenceContext ( PC ): 分为两种, transaction 和 extended. PC 职责:管理实体状态。 Transaction 类型的 PC 在 EntityManager 开始事务时创建,结束事务或事务回滚时关闭,而 Extend PC 可以跨多个事务或非事务。 PC 类型如果是 Transaction ,则 EntityManager 会根据需要创建 PC ,一般情况发生在事务开始时,在事务外调用 EntityManager 的方法也会创建一个临时的 PC ,方法调用结束就删除 PC 。 PC 类型如果是 extended, EntityManager 的整个生命周期只与一个 PC 关联, EntityManager 生命周期的结束也意味着 PC 生命周期的结束。 PC 生命周期:已经在上面说明, PC 生命一旦结束,所以其关联的 Entities 都变为 detached. 注意 Container-managed PC 可以是 transaction OR extended ,而 Application-managed PC ( EntityManager 是程序通过 EntityManagerFactory 创建的)必定是 extended. 为了便于 Persistence Context 在多个 Javaee 组件间共享, Jave ee 提供了 Persistence Context Propagation ,这样就没有必要传递 EntityManager 了。 PC 传递有多种限制请看: http://weblogs.java.net/blog/ss141213/archive/2006/10/persistence_con.html
PersistenceContext 示例:
(http://openjpa.apache.org/builds/1.0.2/apache-openjpa-1.0.2/docs/manual/jpa_overview_emfactory_perscontext.html )
( 1 ) Transaction PC
EntityManager em; // injected
...
// outside a transaction:
// each operation occurs in a separate persistence context, and returns
// a new detached instance (下次使用时需要 merge 一下就行了)
Magazine mag1 = em.find(Magazine.class, magId);
Magazine mag2 = em.find(Magazine.class, magId);
assertTrue(mag2 != mag1);
...
// transaction begins:
// within a transaction, a subsequent lookup doesn't return any of the
// detached objects. however, two lookups within the same transaction
// return the same instance, because the persistence context spans the
// transaction
Magazine mag3 = em.find(Magazine.class, magId);
assertTrue(mag3 != mag1 && mag3 != mag2);
Magazine mag4 = em.find(Magazine.class (magId);
assertTrue(mag4 == mag3);
...
// transaction commits:
// once again, each operation returns a new instance
Magazine mag5 = em.find(Magazine.class, magId);
assertTrue(mag5 != mag3);
( 2 ) Extended PC
EntityManagerFactory emf = ...
EntityManager em = emf.createEntityManager();
// persistence context active for entire life of EM, so only one entity
// for a given persistent identity
Magazine mag1 = em.find(Magazine.class, magId);
Magazine mag2 = em.find(Magazine.class, magId);
assertTrue(mag2 == mag1);
em.getTransaction().begin();
// same persistence context active within the transaction
Magazine mag3 = em.find(Magazine.class, magId);
assertTrue(mag3 == mag1);
Magazine mag4 = em.find(Magazine.class (magId);
assertTrue(mag4 == mag1);
em.getTransaction.commit ();
// when the transaction commits, instance still managed
Magazine mag5 = em.find(Magazine.class, magId);
assertTrue(mag5 == mag1);
// instance finally becomes detached when EM closes
em.close();
Entities :JPA 中实体包含多种状态,这些状态由 PersistenceContext 进行管理。
Transactions : 事务的控制通过 JTA 或 r esource-local EntityTransaction API 实现 , EntityManager 对事物的操纵最终映射到 JTA 或 Resource-local Entity Transaction API 。一个 EntityManager 如果它的事务是由 JTA 控制,叫做 JTA EntityManager ,反之如果是通过 Resource-local Entity Transaction API 控制,叫做 Resource-local EntityManager 。 J2se 只支持 Resource-local 类型的事务。
3. 小结:
JPA 主要有上面提到的四大要素构成,它们相互协作共同完成 OR Maping 。四大要素中最核心的概念是 PersistenceContext , EntityManager 通过与其交互完成对实体的 CRUD 。 PersistenceContext 有两种类型,它的类型决定了其生命周期及 EntityManager 在何时获取销毁它。 Application-managed PC 必然是 Extended ,而 Contained-managedPC 可以是任何一种。 EntityManager 根据事务类型分为 JTA OR Resource-local 两种, java se 只支持 Resourcelocal 类型。最后因 EntityManageFactory 的创建是非常耗资源的,所以一般在整个应用中只创建一次。