web-dev-qa-db-ja.com

Spring Boot 2.0 Hibernate 5 EhCache 3 with JCache

EhCacheを第2レベルのキャッシュとして使用して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を無効にすると(ヒープタグを削除するなどして)エラーが発生するため、xmlが読み取られていることがわかります。

enter image description here

3
George

エンティティの上に@Cacheableアノテーションを設定すると、KEYがエンティティのIDであり、Valueがエンティティである領域が作成されます。上記は、IDであるキーでアクセスするとキャッシュにヒットすることを意味します。 SpringデータとfindByIdを使用すると、キャッシュにヒットします。メソッドfindByNameを作成する場合、アクセスはキーtrerereによるものではないため、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">

ただし、ehcache3にどのように含まれているかはわかりません。 StandartQueryCacheクラスはhibernateパッケージの一部であり、ehcacheパッケージの一部ではないため、同じである必要があると思います。

私もあなたが設定する必要があると思います
hibernate.javax.cache.provider = org.ehcache.jsr107.EhcacheCachingProvider

0