首先,我引用你的问题:
我做错了什么?
你尝试给缓存命名的方式并不适合Hibernate将要使用它的方式。请查看org.hibernate.engine.spi.CacheInitiator
,它使用org.hibernate.internal.CacheImpl
,后者基于:
if ( settings.isQueryCacheEnabled() ) {
final TimestampsRegion timestampsRegion = regionFactory.buildTimestampsRegion(
qualifyRegionName( UpdateTimestampsCache.REGION_NAME ),
sessionFactory.getProperties()
);
updateTimestampsCache = new UpdateTimestampsCache( sessionFactory, timestampsRegion );
...
}
你需要的是 UpdateTimestampsCache.REGION_NAME
(等同于 org.hibernate.cache.spi.UpdateTimestampsCache
)作为缓存名称,对于查询缓存,你必须使用恰好这个缓存名称,不能使用其他名称!
以下是与你的问题相关的其他想法:
- 移除
@Cache
并将缓存名称设置为org.hibernate.cache.spi.UpdateTimestampsCache
将允许你的查询通过hibernate使用ehcache进行缓存(这里不涉及spring缓存抽象)
- 设置硬编码缓存名称可能会使你不高兴,但至少你知道发生了什么
- Balamaci Serban(下面的帖子)非常正确
以下是我的一个项目的配置示例,该示例中ehcache + @Query + @QueryHints可以正常工作(ehcache/ehcache-in-memory.xml
文件):
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="in-memory" xmlns="http://ehcache.org/ehcache.xsd">
<cache name="org.hibernate.cache.internal.StandardQueryCache"
maxElementsInMemory="9999" eternal="false"
timeToIdleSeconds="2592000" timeToLiveSeconds="2592000"
overflowToDisk="false" overflowToOffHeap="false"/>
<cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
maxElementsInMemory="9999" eternal="true"
overflowToDisk="false" overflowToOffHeap="false"/>
<defaultCache maxElementsInMemory="9999" eternal="false"
timeToIdleSeconds="2592000" timeToLiveSeconds="2592000"
overflowToDisk="false" overflowToOffHeap="false"/>
</ehcache>
还有hibernate.properties文件:
hibernate.jdbc.batch_size=20
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.validator.autoregister_listeners=false
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
hibernate.hbm2ddl.auto=update
net.sf.ehcache.configurationResourceName=ehcache/ehcache-in-memory.xml
hibernate.dialect=org.hibernate.dialect.H2Dialect
以下是一些适用于我所解释的pom.xml版本:
<springframework.version>5.0.6.RELEASE</springframework.version>
<spring-security.version>5.0.5.RELEASE</spring-security.version>
<spring-data-jpa.version>2.1.0.RELEASE</spring-data-jpa.version>
<hibernate.version>5.2.13.Final</hibernate.version>
<jackson-datatype-hibernate5.version>2.9.4</jackson-datatype-hibernate5.version>
完整的工作测试位于
image.persistence.repositories.ImageRepositoryTest.java,其链接为:
https://github.com/adrhc/photos-server/tree/how-to-cache-results-of-a-spring-data-jpa-query-method-without-using-query-cache
运行
mvn clean install
或更改我的
env.sh
文件(如果您真的想使用我的shell脚本),然后检查代表3x
imageRepository.count()
调用的SQL查询次数。请注意保留HTML标记。
@Cache
注释对非实体类有作用?该注释应该在实体上使用,而不是任意的类或接口。 - M. DeinumfindAll
没有缓存,除非你在实体上有缓存注释(这是它们应该放置的地方)。如果你试图(或期望)将不可缓存的实体缓存起来,那么它是行不通的,只有查询缓存才能在这种情况下工作。 - M. Deinum