Spring Boot 2.0 Hibernate 5 EhCache 3 与 JCache

我正在尝试使用 EhCache 将 Hibernate 设置为二级缓存,但 TTL 不工作。


这是我的依赖项:


<dependency>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-cache</artifactId>

</dependency>


<dependency>

  <groupId>org.hibernate</groupId>

  <artifactId>hibernate-jcache</artifactId>

</dependency>


<dependency>

  <groupId>org.ehcache</groupId>

  <artifactId>ehcache</artifactId>

</dependency>


<dependency>

  <groupId>javax.cache</groupId>

  <artifactId>cache-api</artifactId>

</dependency>

这是我的 YAML 配置:


spring:

  jpa:

    show-sql: true

    properties:

      hibernate:

        dialect: Dialect

        cache:

          use_second_level_cache: true

          region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory

          use_query_cache: true

  cache:

    jcache:

      config: classpath:ehcache.xml

这是我的实体类的配置方式:


@Entity

@javax.persistence.Cacheable

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)

public class PersonEntity {

  //

}

以及实体的 JpaRepository:


public interface PersonRepository extends JpaRepository<PersonEntity, Integer> {

  @org.springframework.data.jpa.repository.QueryHints({

      @javax.persistence.QueryHint(name = "org.hibernate.cacheable", value = "true")

  })

  List<PersonEntity> findByName(String name);

}

我已将缓存配置为在 2 秒后过期,但调用findByName仍然使用缓存(在第一个之后没有打印 SQL 查询)。


这是ehcache.xml文件:


<?xml version="1.0" encoding="UTF-8"?>

<config xmlns="http://www.ehcache.org/v3">


  <cache-template name="simple">

    <expiry>

      <ttl>2</ttl>

    </expiry>

    <heap>100</heap>

  </cache-template>


  <cache alias="com.sample.PersonEntity" uses-template="simple"/>


</config>

编辑: 我做了一些调试。我在以下位置添加了一个断点org.ehcache.jsr107.ExpiryPolicyToEhcacheExpiry:


javax.cache.expiry.Duration duration = this.expiryPolicy.getExpiryForCreation();

由于某种原因,这个持续时间是无限的。那么也许配置设置不正确?我知道正在读取 xml,因为当我使它无效时(例如通过删除堆标记)我得到一个错误。

http://img2.mukewang.com/639ac45e0001e52002340055.jpg

慕姐8265434
浏览 244回答 2
2回答

蛊毒传说

我想我找到了问题的原因 - 您没有指定ehcache.xml文件的位置:spring:&nbsp; jpa:&nbsp; &nbsp; properties:&nbsp; &nbsp; &nbsp; hibernate:&nbsp; &nbsp; &nbsp; &nbsp; javax.cache:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; provider: org.ehcache.jsr107.EhcacheCachingProvider&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uri: classpath:ehcache.xml&nbsp; &nbsp; &nbsp; &nbsp; cache:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; use_second_level_cache: true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; region.factory_class: jcache&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; use_query_cache: true在这种情况下,Hibernate 使用默认配置创建缓存。我的演示项目日志中的一个片段:17:15:19 WARN [main] org.hibernate.orm.cache: HHH90001006: Missing cache[user] was created on-the-fly. The created cache will use a provider-specific default configuration: make sure you defined one. You can disable this warning by setting 'hibernate.javax.cache.missing_cache_strategy' to 'create'.

当年话下

当您@Cacheable在实体顶部设置注释时,它会创建一个区域,其中KEY是ID实体的,Value是实体。上面的意思是,如果您通过密钥访问,您将命中缓存ID。如果您使用 spring 数据和 findById,它将命中缓存。如果您创建一个方法 findByName,则访问将不是按键 trerefore,因此它不会命中您的Cacheable注释定义的缓存区域。另一方面,它会命中查询缓存,但查询缓存位于完全不同的区域。从您的配置来看,您根本没有配置查询缓存。要使此方法完全命中任何缓存,您需要使用此属性添加它:spring:jpa:properties:hibernate:cache:use_query_cache: true或者,您可以在存储库方法之上指定@Cacheable,这样可以定义一个新区域。您可以配置默认缓存,这应该捕获 StandardQueryCahache。<defaultCache&nbsp;&nbsp; &nbsp; maxElementsInMemory="10000"&nbsp; &nbsp; eternal="false"&nbsp; &nbsp; timeToIdleSeconds="3600"&nbsp; &nbsp; timeToLiveSeconds="3600">&nbsp; </defaultCache>在 EhCache2 中,您可以通过此元素配置标准查询缓存:&nbsp; <cachename="org.hibernate.cache.internal.StandardQueryCache"maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="3600"timeToLiveSeconds="3600">虽然不确定它在 ehcache 3 中的表现如何。我相信它应该是一样的,因为 StandartQueryCache 类是 hibernate 包的一部分,而不是 ehcache 包的一部分。我还认为你需要设置hibernate.javax.cache.provider = org.ehcache.jsr107.EhcacheCachingProvider
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java