我使用 Spring Boot 1.2.5 和 JPA2 来注释实体(并将 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)
这样的查询仍然会触发数据库查询,而不是使用缓存的数据。
知道缺少什么吗?
最佳答案
总结所有内容(L2 缓存和查询缓存):
要做的第一件事是将缓存提供程序(我建议使用 EhCache)添加到您的类路径中。
hibernate <5.3
添加 hibernate-ehcache
依赖项。该库包含 EhCache 2,现已停产。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>your_hibernate_version</version>
</dependency>
hibernate >=5.3
在较新版本的 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 with @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(或 Hibernate >=5.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
关于hibernate - Spring Boot + JPA2 + Hibernate - 启用二级缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31585698/