我正在使用带有JPA2的Spring Boot 1.2.5来注释实体(并将hibernate作为JPA实现的底层)。
我想在该设置中使用二级缓存,因此实体使用@javax.persistence.Cacheable
进行注释
我还在application.properties中添加了以下内容:
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
在启动期间,hibernate抱怨缺少EhCacheRegionFactory
所以我也把它添加到pom:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
</dependency>
但仍然像entityManager.find(Clazz.class, pk)
这样的查询正在触发数据库查询而不是使用缓存数据。
知道缺少什么吗?
好吧,经过一些挖掘,这是我在application.properties
中遗漏的东西:
spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
希望它可以帮助别人:)
要总结所有内容(二级缓存和查询缓存):
首先要做的是将缓存提供程序(我建议使用EhCache)添加到类路径中。
在以前版本的Hibernate(5.3之前)中,通过添加此依赖项来完成。此依赖项包含EhCache 2,现已停止使用。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>your_hibernate_version</version>
</dependency>
在较新版本的Hibernate中,应该使用实现JSR-107(JCache)API的缓存。因此需要2个依赖项 - 一个用于JSR-107 API,第二个用于实际的JCache实现(EhCache 3)。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>your_hibernate_version</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.6.3</version>
<scope>runtime</scope>
</dependency>
现在让我们转到application.properties/yml文件:
spring:
jpa:
#optional - show SQL statements in console.
show-sql: true
properties:
javax:
persistence:
sharedCache:
#required - enable selective caching mode - only entities using @Cacheable annotation will use L2 cache.
mode: ENABLE_SELECTIVE
hibernate:
#optional - enable SQL statements formatting.
format_sql: true
#optional - generate statistics to check if L2/query cache is actually being used.
generate_statistics: true
cache:
#required - turn on L2 cache.
use_second_level_cache: true
#optional - turn on query cache.
use_query_cache: true
region:
#required - classpath to cache region factory.
factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory
对于EhCache 3,应使用此区域工厂:
factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
您还可以为Hibernate启用TRACE级别日志记录以验证您的代码和配置:
logging:
level:
org:
hibernate:
type: trace
现在让我们转到代码。要在您的实体上启用L2缓存,您需要添加这两个注释:
@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) //Provide cache strategy.
public class MyEntity {
...
}
注意 - 如果要缓存@OneToMany
或@ManyToOne
关系,请在此字段上添加@Cache
注释。
要在spring-data-jpa存储库中启用查询缓存,您需要添加适当的QueryHint
。
public class MyEntityRepository implements JpaRepository<MyEntity, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<MyEntity> findBySomething(String something);
}
现在验证通过日志,如果您的查询只执行一次,并记得关闭所有调试的东西 - 现在你已经完成了。
注2 - 如果你希望保留默认值而不在日志中收到警告,你也可以将missing cache strategy定义为create
:
spring:
jpa:
properties:
hibernate:
javax:
cache:
missing_cache_strategy: create
@Daimon我不确定,是否
spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
是最好的决定。
引自qazxsw poi
默认情况下,实体不是二级缓存的一部分,我们建议您坚持使用此设置。但是,您可以通过在persistence.xml文件中设置shared-cache-mode元素或在配置中使用javax.persistence.sharedCache.mode属性来覆盖它。
而
ENABLE_SELECTIVE(默认值和建议值):除非明确标记为可缓存,否则不会缓存实体。
那么,是不是,你没有用@ javax.persistence.Cacheable或@ org.hibernate.annotations.Cache注释所有受影响的实体?这可能会导致影响,查询缓存尝试在二级缓存中查找受影响的实体但未成功,然后开始通过单个选择获取每个实体。
您应该在类路径中有一个ehcache.xml文件。该文件应至少包含默认缓存策略。为了更容易进行调试,请确保实体不会从缓存中逐出,这样做是永恒的:
ehcache.xml中:
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
为了确保一切正常,您应该在应用程序启动期间拥有以下日志:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
Name="CacheManager"
maxBytesLocalHeap="250m">
<defaultCache eternal="true"
...
/>
<cache name="org.hibernate.cache.internal.StandardQueryCache"
eternal="true"
...
/>
这意味着您的实体缓存注释已被正确加入,并将使用默认缓存。
如果使用Could not find a specific ehcache configuration for cache named [com.yourcompany.YourClass]; Using defaults.
进行测试,那么它不会包含查询缓存,而只会包含实体缓存。查询缓存用于查询(em.createQuery(...)和关系发送
另外,我使用org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory,但我不知道哪个更好。
您可以在JCache,Ehcache,Gvava Cache,Hazelcast Cache,Caffeine Cache中使用第三方缓存提供程序。
请参考entityManager.find(Clazz.class, pk)
上的这个答案,了解如何在Spring启动中启用和配置二级缓存。