簡體   English   中英

帶有JCache的Spring Boot 2.0 Hibernate 5 EhCache 3

[英]Spring Boot 2.0 Hibernate 5 EhCache 3 with 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類的配置方式:

@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,因為當我使它無效時(例如,通過刪除堆標記),我得到一個錯誤。

在此處輸入圖片說明

我想我找到了問題的原因-您未指定ehcache.xml文件的位置:

spring:
  jpa:
    properties:
      hibernate:
        javax.cache:
          provider: org.ehcache.jsr107.EhcacheCachingProvider
          uri: classpath:ehcache.xml
        cache:
          use_second_level_cache: true
          region.factory_class: jcache
          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,則將無法通過鍵trere進行訪問,然后才能訪問您的Cacheable批注定義的緩存區域。 另一方面,它將命中查詢緩存,但查詢緩存位於完全不同的區域。 從您的配置來看,您根本沒有配置查詢緩存。要使此方法完全訪問任何緩存,您需要使用以下屬性添加它:

spring:jpa:properties:hibernate:cache:use_query_cache: true

或者,您可以在存儲庫方法的頂部指定@Cacheable,從而定義一個新區域。

您可以配置默認緩存,這應該捕獲StandardQueryCahache。

<defaultCache 
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="3600"
    timeToLiveSeconds="3600">
  </defaultCache>

在EhCache2中,您可以通過以下元素配置標准查詢緩存:

  <cache
name="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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM