JPA 2.0 Vs Hibernate:缓存方法的差异(一)

EJB 3.0软件专家组在2009年11月发布了最新版本JPA 2.0(JSR 317),改进了JPA 1.0版本中的一些基本功能:ORM功能、实体管理功能、查询接口和Java持久化查询语言(JPQL)。

作为JPA Provider中最强大的Hibernate通过Hibernate Annotation和Hibernate EntityManager库实施JPA。Hibernate EntityManager库是JPA的完整实现,它遵循的是JPA持久化特征,而Hibernate Annotation是除了标准化的JPA部分特定于Hibernate,它遵循自由化特征。Hibernate 从3.2开始,就开始兼容JPA。Hibernate3.2获得了Sun TCK的JPA(Java Persistence API) 兼容认证。2010年3月发布的Hibernate 3.5现在已经完全兼容JPA 2.0。Hibernate Annotations、Hibernate EntityManager和Hibernate Envers已经整合为JPA 2.0项目核心的部分。

是什么让这两个不同的ORM框架兼容的呢?在这篇文章中,我们将对JPA 2.0和Hibernate的缓存方法进行一个简单的比较。首先,我们先介绍一下JPA 2.0缓存原理。

JPA 2.0缓存原理

缓存对应用程序性能和数据库访问的优化是必不可少的。通过存储所需服务请求的数据,减少访问缓存从数据库调用数据的时间。JPA 2.0支持两个级别的缓存,JPA的一级缓存(L1)和JPA的二级缓存(L2)。

JPA的1级缓存

一个JPA entity manager使用的持久化上下文管理的框架。在持久性方面,与各自的entity manager作为第一级缓存。在任何一个持久化对象的框架内,将一个entity manager只有一个点的对象映射到数据库中特定的实例。当另一个用户不同的持久化对象,JPA圈定持久性对象的范围,以减少访问的时间。

持久性对象可以在任何程序执行的过程中。在程序执行的过程中,当一个用户在多个持久化对象之间来回调用,程序结束后马上跳出。坚持在一个不同的持久化对象之间进行独立实体的变化,而合并操作是在entity manager使用。

下面是一个例子:

@Stateless  


public EmpDetailsBean implements EmpDetails {  


@PersistenceContext  


EntityManager entityManager;  


 


public Employee addEmployee(String empId, String empName, String empUni) {  



Employee employee = new Employee(empId, empName, empUnit);  



entityManager.persist(employee); //employee is managed entity  


return employee; //employee is detached entity  


}  


 


public Employee updateEmployee(Employee employee) {  


//employee is detached entity, employee1 is managed entity  



Employee employee1 = entityManager.merge(employee);  



return employee;  


}  


}  


 

扩大一下范围,在多个持久化对象之间来回调用,因此对实体集并不是脱离,他们依然管理。扩展的范围适合应用场合在用户跨越多个请求。

下面是一个扩大范围的例子:

@Stateful  


public EmpDetailsBean implements EmpDetails {  



@PersistenceContext(type=PersistenceContextType.EXTENDED)  



EntityManager entityManager;  


//Cached employee  


private Employee employee;  


 


public void addEmployee(String empId, String empName, String empUnit) {  



employee = new Employee(empId, empName, empUnit);  



entityManager.persist(employee); //employee is managed entity  


}  


 


public void updateEmployee(String empUnit) {  


employee.setUnit(empUnit); //employee is managed entity  


}  


}  


 

然而,扩大使用范围,缓存的内存消耗需要进行评估,是利用缓存调用消耗少还是直接访问数据库方便。图1显示JPA 1级缓存。

JPA 2.0 Vs Hibernate:缓存方法的差异(一)
JPA Level 1 (L1) Cache

JPA 2.0的二级缓存

二级缓存被引进的JPA 2.0版本。JPA提供了基本的缓存操作的缓存API,而2级缓存共享状态的实体跨越不同的持久化对象。 2级缓存的持久化对象的基础,这是高度透明的应用程序。图2显示了JPA 2.0级缓存。

JPA 2.0 Vs Hibernate:缓存方法的差异(一) 
JPA Level 2 (L2) Cache

二级高速缓存通常是用来提高性能。但是,使用缓存可能会导致提取“陈旧”数据,因此您可以选择禁用缓存。

public interface Cache {  


/**  


* Whether the cache contains data for the given entity.  


*/  


public boolean contains(Class cls, Object primaryKey);  


 


/**  


* Remove the data for the given entity from the cache.  


*/  


public void evict(Class cls, Object primaryKey);  


 


/**  


* Remove the data for entities of the specified class (and its  


* subclasses) from the cache.  


*/  


public void evict(Class cls);  


 


/**  


* Clear the cache.  


*/  


public void evictAll();  


}  


 

JPA的2.0缓存API还提供了允许您刷新或绕过使用查询提示,两个实例:CacheRetrieveMode和CacheStoreMode定义缓存。您使用CacheRetrieveMode读取缓存数据:

javax.persistence.cache.retrieveMode: CacheRetrieveMode  


 

绕过缓存,您将直接从数据库中获取数据。

您使用CacheStoreMode插入或更新到缓存中,在读取数据时从数据库中调取实体数据,如下:

javax.persistence.cache.storeMode: CacheStoreMode  


 

当CacheStoreMode不会强制一个已经缓存的项目时,从数据库中读取刷新的数据。

在刷新、插入或更新到缓存读取数据时,将强制从数据库中读取项目缓存的刷新。

当二级缓存被启用,第一次提取持久性提供的程序将寻找在持久化对象的实体。如果它不容易找到他们,而不是发送查询到数据库缓存中。

这里是JPA的二级缓存优点和缺点:

优点:

◆避免了已经加载对象的数据库访问

◆对于频繁访问的未修改的对象读取更快

缺点:

◆内存消耗大量的对象

◆更新陈旧的数据对象

◆需要对可扩展性差的对象进行频繁更新

◆增加并发代码拼写

二级缓存最好是经常阅读经常修改的数据,而不是至关重要的。

原文名称:JPA 2.0 Cache Vs. Hibernate Cache: Differences in Approach

相关推荐