当前位置: 首页 > 知识库问答 >
问题:

Spring Boot JPA2 Hibernate-启用二级缓存

缑高朗
2023-03-14

我使用SpringBoot1.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)这样的查询仍在触发DB查询,而不是使用缓存数据。

你知道少了什么吗?

共有3个答案

柏正平
2023-03-14

@Daimon我不确定是否

spring.jpa.properties.javax.persistence.sharedCache.mode=ALL

是最好的决定。

引自Hibernate 20.2.1。缓存映射文档部分

默认情况下,实体不是二级缓存的一部分,建议您坚持此设置。但是,您可以通过在persistence.xml文件中设置共享缓存模式元素或在配置中使用javax.persistence.sharedCache.mode属性来覆盖这一点。

然而

ENABLE_SELECTIVE(默认值和建议值):除非显式标记为可缓存,否则不会缓存实体。

那么,您是否还没有用@javax.persistence.Cacheable或者更确切地说@org.hibernate.annotations.Cache注释所有受影响的实体?这可能会导致查询缓存试图在二级缓存中查找受影响的实体但未成功,然后通过单个选择开始获取每个实体。

奚翰海
2023-03-14

经过进一步的挖掘,以下是我在application.properties中缺少的:

spring.jpa.properties.javax.persistence.sharedCache.mode=ALL

希望对某人有所帮助:)

怀浩大
2023-03-14

将所有内容(L2缓存和查询缓存)加起来:

首先要做的是向类路径添加缓存提供程序(我建议使用EhCache)。

冬眠

添加hibernate-ehache依赖项。此库包含EhCache 2,现已停用。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>your_hibernate_version</version>
</dependency>

冬眠

在新版本的Hibernate缓存中,应该使用实现JSR-107(JCache)API的缓存。因此需要两个依赖项—一个用于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

factory_class: org.hibernate.cache.jcache.JCacheRegionFactory

您还可以为Hibernate启用跟踪级别日志记录,以验证代码和配置:

logging:
  level:
    org:
      hibernate:
        type: trace

现在让我们继续讨论代码。要在实体上启用二级缓存,需要添加以下两个注释:

@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) //Provide cache strategy.
public class MyEntity {
  ...
}

注意-如果要缓存您的@OneToMany@ManyToOne关系,请在该字段上添加@cache注释。

要在sping-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-如果你想保持默认值而不在日志中得到警告,你也可以将丢失的缓存策略定义为创建:

spring:
  jpa:
    properties:
      hibernate:
        javax:
          cache:
            missing_cache_strategy: create
 类似资料:
  • 当你使用本地(在内存中)缓存时,服务器可以缓存一些信息并快速地检索它,但是其他服务器不能访问这个缓存数据,他们需要到数据库中查询同样的信息。 如果你喜欢使用分布式缓存让其他服务器访问缓存的数据,由于它有一些序列化/反序列化和网络延迟开销,则需要注意:在某些情况下,它可能会降低性能。 缓存需要处理的另一个问题:缓存失效。 There are only two hard things in Compu

  • 1、一级缓存:指的是mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入sqlSession中,再次查询的时候,先去sqlSession中查询,有的话直接拿出,当sqlSession消失时,mybatis的一级缓存也就消失了,当调用sqlSession的修改、添加、删除、commit()、close()等方法时,会清空一级缓存。 2、二级缓存:指的是mybati

  • 问题内容: 使用Java Persistence API(带注释的实体)时,启用Hibernate的二级缓存需要采取哪些步骤?我如何检查它是否正常工作?我正在使用JBoss4.2.2.GA。 从Hibernate文档中,我似乎需要启用缓存并在 persistence.xml中 指定一个缓存提供程序,例如: 还需要什么?我是否需要在JPA实体中添加 @Cache 注释? 如何判断缓存是否正常工作?我

  • 问题内容: 我想在hibernate项目中使用二级缓存,但是我只对hibernate二级缓存了解一点,任何人都可以解释我应该如何在代码中使用它以及需要什么配置和.jar文件吗?我将这些设置设置为我的hibernate.cfg.xml文件 并添加这些jar文件, 我想知道我是否需要更改其他配置? 我怎么知道我的项目使用二级缓存? 如果只是设置此设置,hibernate将自动使用此设置,否则我必须在我

  • 本文向大家介绍Mybatis 的一级、二级缓存相关面试题,主要包含被问及Mybatis 的一级、二级缓存时的应答技巧和注意事项,需要的朋友参考一下 1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就 将清空,默认打开一级缓存。 2)二级缓

  • [命名空间: Serenity] - [程序集: Serenity.Core] 开箱即用,TwoLevelCache 提供了我们讨论的所有甚至更多的功能。 public static class TwoLevelCache { public static TItem Get<TItem>( string cacheKey, TimeSpan