hibernate - Spring Boot + JPA2 + Hibernate - 启用二级缓存

标签 hibernate spring-boot jpa-2.0 second-level-cache

我使用 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/

相关文章:

java.sql.SQLSyntaxErrorException : Unknown column 'student0_.student_id' in 'field list'

java - 奇怪的 Spring Transactional JUnit 测试 Hibernate 实体为 null

java - 无法编译项目:lombok创建的Getter不起作用

Java Spring Hibernate 将重复值保存到 MySQL 表会引发错误

java - Hibernate - 如何检查用户是否存在?

spring-boot - 无法找到请求目标的有效证书路径 - Keycloak - Springboot - 自签名证书 - 测试

java - 使用 JSON 通过 Spring Boot 格式化 Java 时间

java - 对多个字段施加唯一约束

hibernate - JPQL 构造函数表达式 - org.hibernate.hql.ast.QuerySyntaxException :Table is not mapped

java - @XmlTransient 用于序列化但不用于反序列化?