When 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:
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?
It turns out that my fear was unfounded. This is indeed operating as indicated by the Hibernate documentation: the query cache is returning only entity identifiers and Hibernate is then assembling those entities individually.
My confusion regarding infinispan-configs.xml's namedCaches, "entity," and, "timestamps," derives only from a false expectation. Since the namedCache, "local-query," was defined in infinispan-configs.xml, and the CacheManager JMX attributes showed a cache named "local-query" created, I expected that the same would hold for, "timestamps," and, "entity." This is not so. These namedCaches will always be indicated (not created) in the CacheManager JMX attributes: timetamps, entity, entity-repeatable, replicated-query, and replicated-entity. Nonetheless the configurations of these namedCaches are honored, but the names in the CacheManager JMX attributes will not match, unlike "local-query." Instead, they will be the cache region name: for timestamps, "org.hibernate.cache.UpdateTimestampsCache," and for entities, the package-qualified java class name of the entity.
I also determined why I was getting no cache hits in the JMX statistics for my level-2 entity cache regions, despite that those regions were correctly backing the query cache. My test and the application code were set up in such a way that every entity returned in the result sets from the query cache was already in the PersistenceContext aka Session aka Hibernate Level-1 cache, and so during assembly of the result sets due to a query cache hit, they were served from there rather than from the level-2 entity cache regions.
精彩评论