How to enable JPA L2 entity cache to back the query cache
timheilman May 13, 2011 5:28 PMWhen using Hibernate 3.5.6-FINAL as our JPA provider, and infinispan 4.2.0.ALPHA1 as the level-2 query cache provider, I am worried that, contrary to the Hibernate documentation, database results are being stored multiple times in distinct memory locations (for different HQL queries' resultsets that return some of the same records) within the infinispan namedCache, "local-query". Because many of our frequently-issued queries have a large intersection in their result sets, this could quickly exhaust memory and render the query cache useless.
I suspect I am misconfiguring either infinispan or hibernate or both, as I can't seem to get the hibernate 2nd-level *entity* cache operational as a backing for the query cache. I would love to see an example of infinispan as a hibernate-as-JPA level-2 query cache whose results are themselves backed by infinispan as a hibernate-as-JPA level-2 *entity* cache.
Details:
Hibernate 3.5 documentation ( http://docs.jboss.org/hibernate/core/3.5/reference/en/html/performance.html#performance-querycache-enable ) claims:
bq. The query cache does not cache the state of the actual entities in the cache; it caches only identifier values and results of value type. For this reaso, [sic] the query cache should always be used in conjunction with the second-level cache for those entities expected to be cached as part of a query result cache
However, enabling the hibernate level-2 query cache using infinispan (per http://community.jboss.org/wiki/usinginfinispanasjpahibernatesecondlevelcacheprovider) like so in our persistence.xml:
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/>
<property name="hibernate.cache.infinispan.statistics" value="true"/>
and examining the infinispan CacheManager JMX attributes shows only one of the six namedCaches defined in infinispan-configs.xml (from GAV org.hibernate/hibernate-infinispan/3.5.6-FINAL, which depends on GAV org.infinispan/infinispan-core/4.2.0.ALPHA1) gets created, along with one not defined there:
org.hibernate.cache.UpdateTimestampsCache(created)
timestamps(not created)
entity-repeatable(not created)
entity(not created)
local-query(created)
replicated-query(not created)
replicated-entity(not created)
I suspect that the jboss wiki article referenced above, when it discusses the entity cache, is referring to the namedCache "entity"; however, I can't find how to get that cache created. (Aside: I also worry that infinispan-configs.xml's local-query is created but infinispan-configs.xml's timestamps is not; instead we receive an UpdateTimestampsCache that must be defined elsewhere in hibernate.) Specifying
<property name="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE"/>
in our persistence.xml and then annotating relevant entities @javax.persistence.Cacheable does (according to the infinispan CacheManager JMX attributes) get entity caches created (named as the package-qualified java class name of the entity), but they seem unused even when the JMX statistics show a high hit ratio for local-query (and indeed, spectacular performance for such cache-hitting queries).
Is my fear unfounded and under the covers infinispan is storing an entity's information only once even when it is returned in multiple HQL queries' resultsets? If not, what is the proper way to get infinispan-configs.xml's namedCache, "entities" used to avoid that duplicate-storage of entity data? Finally, how can infinispan-configs.xml's namedCache, "timestamps" be used, rather than "org.hibernate.cache.UpdateTimestampsCache", as the hibernate level-2 timestamp cache?