当使用Hibernate 3.5.6-FINAL作为我们的JPA提供程序,并且infinispan 4.2.0.ALPHA1作为level-2查询缓存提供程序时,我担心,与Hibernate文档相反,数据库结果被多次存储在infinispan namedCache,“local-query”中的不同内存位置(对于返回一些相同记录的不同HQL查询结果集)。因为我们的许多经常发出的查询在其结果集中都有一个大的交集,所以这可能会快速耗尽内存并使查询缓存无效。
我怀疑我错误配置infinispan或hibernate或两者兼而有之,因为我似乎无法让hibernate二级实体缓存作为查询缓存的支持。我希望看到infinispan作为hibernate-as-JPA level-2查询缓存的示例,其结果本身由infinispan作为hibernate-as-JPA level-2 实体缓存支持。
详细说明:
Hibernate 3.5文档(http://docs.jboss.org/hibernate/core/3.5/reference/en/html/performance.html#performance-querycache-enable)声明:
查询缓存不会缓存缓存中实际实体的状态;它仅缓存标识符值和值类型的结果。对于此reaso,[sic]查询缓存应始终与二级缓存一起使用,以用于那些预期作为查询结果缓存的一部分进行缓存的实体
但是,在我们的persistence.xml中使用infinispan(per http://community.jboss.org/wiki/usinginfinispanasjpahibernatesecondlevelcacheprovider)启用hibernate level-2查询缓存:
<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"/>
并检查infinispan CacheManager JMX属性只显示infinispan-configs.xml中定义的六个namedCaches中的一个(来自GAV org.hibernate / hibernate-infinispan / 3.5.6-FINAL,这取决于GAV org.infinispan / infinispan -core / 4.2.0.ALPHA1)被创建,还有一个未在那里定义:
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)
我怀疑上面引用的jboss wiki文章在讨论实体缓存时指的是namedCache“实体”;但是,我找不到如何创建缓存。 (旁白:我还担心infinispan-configs.xml的本地查询已创建,但infinispan-configs.xml的时间戳不是;而是我们收到一个必须在hibernate的其他地方定义的UpdateTimestampsCache。)指定
<property name="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE"/>
在我们的persistence.xml中,然后注释相关实体@javax.persistence.Cacheable(根据infinispan CacheManager JMX属性)获取实体缓存(命名为实体的包限定java类名),但是它们即使JMX统计数据显示本地查询的命中率很高(事实上,这种缓存命中查询的性能也非常惊人),它们似乎还没有使用。
我的恐惧是否毫无根据,并且即使在多个HQL查询的结果集中返回实体的信息时,infinispan只存储一个实体的信息?如果没有,获取infinispan-configs.xml的namedCache的正确方法是什么,“实体”用于避免实体数据的重复存储?最后,如何使用infinispan-configs.xml的namedCache,“timestamps”而不是“org.hibernate.cache.UpdateTimestampsCache”作为hibernate level-2时间戳缓存?
答案 0 :(得分:3)
事实证明,我的恐惧是没有根据的。这确实是在Hibernate文档中指出的:查询缓存只返回实体标识符,然后Hibernate会单独组装这些实体。
我对infinispan-configs.xml的namedCaches,“entity”和“timestamps”的困惑只来自于错误的期望。由于在Infinispan-configs.xml中定义了namedCache,“local-query”,并且CacheManager JMX属性显示了一个名为“local-query”的缓存,我预计同样适用于“timestamps”,以及“实体。”事实并非如此。这些namedCaches将始终始终在CacheManager JMX属性中指示(未创建):timetamps,entity,entity-repeatable,replicated-query和replicated-entity。尽管如此,这些namedCaches 的配置仍然是,但与“local-query”不同,CacheManager JMX属性中的名称将不匹配。相反,它们将是缓存区域名称:对于时间戳,“org.hibernate.cache.UpdateTimestampsCache”,对于实体,它们是实体的包限定的java类名。
我还确定了为什么我在我的第2级实体缓存区域的JMX统计信息中没有获得缓存命中,尽管这些区域正确支持查询缓存。我的测试和应用程序代码的设置方式使得从查询缓存返回的结果集中的每个实体都已经在PersistenceContext又称为Session Hibernate Level-1缓存中,因此在组装结果集时由于查询缓存命中,它们是从那里而不是从二级实体缓存区域提供的。