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が読み取られていることがわかります。
エンティティの上に@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