Level 2 cache is one of the most powerful features of the JPA spec. It’s a transparent layer that manages out-of-session data access and cranks-up the performance of the data access tier. To my knowledge it has been first seen in Hibernate and was later adopted by the then-emerging JPA spec (driven mostly by the Hibernate guys back in the day).
As annotations gained strength and adoption, L2 caching that was initially configured through XML or properties files, was brought closer to the source code, alas in different forms and shapes. This becomes apparent if you ever have to deploy your webapp across a multitude of containers as you have to painfully recode the cache configuration (or worse, hand-coded cache access). Why not standardizing the cache control in JPA? This seems to be simple enough to achieve and yet it isn’t there. Now that JPA 2.0 is standardizing on Level 2 cache access (See JSR 317 section 6.10) it is the natural thing to do.
Every JPA provider has its own way of specifying cache access (both Entity and query cache).
To grasp the extent of the various ways cache is configured, here are some examples:
Hibernate:
Cache control for entities
@Entity @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public class Employee {...
Cache control for named queries:
@javax.persistence.NamedQuery(name="findEmployeesInDept", query="select emp from Employee emp where emp.department = ?1", hints={@QueryHint(name="org.hibernate.cacheable",value="true")}) or @org.hibernate.annotations.NamedQuery(cacheable=true, cacheRegion="employeeRegion")
OpenJPA
Cache control for entities
@Entity @org.apache.openjpa.persistence.DataCache(timeout=10000) public class Employee {...
Query cache requires hand coded cache access:
OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf); QueryResultCache qcache = oemf.getQueryResultCache();
Continue reading “Proposal to standardize the Level 2 query cache configuration in JPA 2.0”