1.持久化上下文
持久化单元(persist unit)就是关于一组Entity的命名配置。持久化单元是一个静态概念。
持久化上下文(Persist Context)就是一个受管的Entity实例的集合。
每一个持久化上下文都关联一个持久化单元,持久化上下文不可能脱离持久化单元独立存在。
持久化上下文是一个动态概念。
尽管持久化上下文非常重要,但是开发者不直接与之打交道,持久化上下文在程序中是透明的,我们通过EntityManager间接管理它。
2.三个类:Persistence,EntityManagerFactory和EntityManager
实体管理器工厂 EntityManagerFactory是获得实体管理器EntityManager对象的入口,
而EntityManagerFactory对象是通过javax.persistenc.Persistence类中的静态方法createEntityManagerFactory来创建的。
javax.persistenc.Persistence API
- javax.persistenc.Persistence类提供了两个手动创建EntityManagerFactory对象的方法,它们的定义如下所示。
package javax.persistence;
import java.util.*;
publicclassPersistence {
publicstatic EntityManagerFactory createEntityManagerFactory(
String persistenceUnitName) {...}
publicstatic EntityManagerFactory createEntityManagerFactory(
String persistenceUnitName, Map properties) {...}
}
- 其中,createEntityManagerFactory(String persistenceUnitName, Map properties)方法中properties的参数将覆盖persistence.xml文件配置的参数。
EntityManagerFactory API
package javax.persistence;
import java.util.Map;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.criteria.CriteriaBuilder;
/**
* Interface used to interact with the entity manager factory
* for the persistence unit.
*
* <p>When the application has finished using the entity manager
* factory, and/or at application shutdown, the application should
* close the entity manager factory. Once an
* <code>EntityManagerFactory</code> has been closed, all its entity managers
* are considered to be in the closed state.
*
* @since Java Persistence 1.0
*/
publicinterfaceEntityManagerFactory {
/**
* Create a newapplication-managed <code>EntityManager</code>.
* This method returns a new <code>EntityManager</code> instance each time
* it is invoked.
* The <code>isOpen</code> method will returntrue on the returned instance.
* @return entity manager instance
* @throws IllegalStateException if the entity manager factory
* has been closed
*/
public EntityManager createEntityManager();
/**
* Create a newapplication-managed <code>EntityManager</code> with the
* specified Map of properties.
* This method returns a new <code>EntityManager</code> instance each time
* it is invoked.
* The <code>isOpen</code> method will returntrue on the returned instance.
* @param map properties for entity manager
* @return entity manager instance
* @throws IllegalStateException if the entity manager factory
* has been closed
*/
public EntityManager createEntityManager(Map map);
/**
* Return an instance of <code>CriteriaBuilder</code> for the creation of
* <code>CriteriaQuery</code> objects.
* @return CriteriaBuilder instance
* @throws IllegalStateException if the entity manager factory
* has been closed
*
* @since Java Persistence 2.0
*/
public CriteriaBuilder getCriteriaBuilder();
/**
* Return an instance of <code>Metamodel</code> interfacefor access to the
* metamodel of the persistence unit.
* @return Metamodel instance
* @throws IllegalStateException if the entity manager factory
* has been closed
*
* @since Java Persistence 2.0
*/
public Metamodel getMetamodel();
/**
* Indicates whether the factory is open. Returns true
* until the factory has been closed.
* @returnboolean indicating whether the factory is open
*/
publicbooleanisOpen();
/**
* Close the factory, releasing any resources that it holds.
* After a factory instance has been closed, all methods invoked
* on it will throw the <code>IllegalStateException</code>, except
* for <code>isOpen</code>, which will returnfalse. Once an
* <code>EntityManagerFactory</code> has been closed, all its
* entity managers are considered to be in the closed state.
* @throws IllegalStateException if the entity manager factory
* has been closed
*/
publicvoidclose();
/**
* Get the properties and associated values that are in effect
* for the entity manager factory. Changing the contents of the
* map does not change the configuration in effect.
* @return properties
* @throws IllegalStateException if the entity manager factory
* has been closed
*
* @since Java Persistence 2.0
*/
public Map<String, Object> getProperties();
/**
* Access the cache that is associated with the entity manager
* factory (the "second level cache").
* @return instance of the <code>Cache</code> interface
* @throws IllegalStateException if the entity manager factory
* has been closed
*
* @since Java Persistence 2.0
*/
public Cache getCache();
/**
* Return interfaceproviding access to utility methods
* for the persistence unit.
* @return <code>PersistenceUnitUtil</code> interface
* @throws IllegalStateException if the entity manager factory
* has been closed
*
* @since Java Persistence 2.0
*/
public PersistenceUnitUtil getPersistenceUnitUtil();
}
- 独立运行环境下:
EntityManagerFactoryemf= Persistence.createEntityManagerFactory("JPA");
EntityManagerentityManger= emf.createEntityManager();
- 使用容器的环境下,不需要通过Persistence创建EntityManagerFactory和EntityManger,而是通过注解实现
@PersistenceContext
private EntityManger entityManger;
@PersistenceUnit
private EntityMangerFactory emf;
- 实体管理器EntityManager是负责管理Entity的对象。对Entity的操作包括添加、删除、修改和查询,都是通过实体管理器来实现的。
依赖注入EntityManager
- 在EJB容器 中,EntityManager的获得可以通过标注,使用依赖注入来创建EntityManager实例,代码如下所示。
Public classsessionbean1{
@PersistenceContext
EntityManager em;
。。。
}
- 通过将@PersistContext注解标注在EntityManager类型的字段上,这样得到的EntityManager就是容器管理的EntityManager,我们不需要也不应该显式的关闭注入的EntityManager实例。
- @PersistenceContex 表示标注的属性entityManager是一个实体管理器EntityManager对象,EJB容器会根据unitName的值来初始化 EntityManager。
- 注意:如果persistence.xml文件中配置了多个<persistence-unit>。
- 那么在注入EntityManager对 象时必须指定持久化名称,通过@PersistenceContext注释的unitName属性进行指定,例:
@PersistenceContext(unitName="foshanshop")
EntityManager em;
- 如果只有一个<persistence-unit>,不需要明确指定。
- 请注意:Entity Bean被EntityManager管理时,EntityManager会跟踪他的状态改变,在任何决定更新实体Bean的时候便会把发生改变的值同步 到数据库中(跟hibernate一样)。
- 但是如果entity Bean从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中,每次方法调用使用的都是相同的持久化上下文,所以前一次方法调用产生的受管实体下一个方法访问时仍然是受管实体。
参考来源: http://jpa.group.iteye.com/group/topic/34229