JPA2でSpring Boot 1.2.5を使用してエンティティに注釈を付けています(およびJPA実装の基礎として休止状態になっています)。
そのセットアップで2次キャッシュを使用したかったため、エンティティに_@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
_
起動時に休止状態がEhCacheRegionFactory
の欠如について不平を言ったので、私もこれをpomに追加しました:
_<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
</dependency>
_
ただし、entityManager.find(Clazz.class, pk)
などのクエリは、キャッシュされたデータを使用する代わりにDBクエリを起動しています。
何が欠けているのでしょうか?
さて、もう少し掘り下げてみると、application.properties
:
spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
それが誰かを助けることを願っています:)
すべて(L2キャッシュとクエリキャッシュ)を合計するには:
最初に行うことは、キャッシュプロバイダー(EhCacheの使用をお勧めします)をクラスパスに追加することです。
Hibernateの以前のバージョン(5.3より前)では、hibernate-ehcache依存関係を追加することにより行われました。このライブラリには、現在廃止されているEhCache 2が含まれています。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>your_hibernate_version</version>
</dependency>
Hibernateキャッシュの新しいバージョンでは、JSR-107(JCache)APIを実装する必要があります。そのため、2つの依存関係が必要です。1つはJSR-107 API用で、もう1つは実際の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 using @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の場合、このリージョンファクトリを使用する必要があります。
factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
HibernateのTRACEレベルのログ記録を有効にして、コードと設定を確認することもできます。
logging:
level:
org:
hibernate:
type: trace
それでは、コードに移りましょう。エンティティでL2キャッシングを有効にするには、これらの2つのアノテーションを追加する必要があります。
@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) //Provide cache strategy.
public class MyEntity {
...
}
注-@OneToMany
または@ManyToOne
関係をキャッシュする場合-このフィールドに@Cache
注釈を追加しますまあ。
また、spring-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);
}
クエリが1回だけ実行されたかどうかをログで確認し、すべてのデバッグ機能をオフにすることを忘れないでください。これで完了です。
注2- missing cache strategy as create
としても定義できます。ログに警告が表示されます:
spring:
jpa:
properties:
hibernate:
javax:
cache:
missing_cache_strategy: create
@ Daimon 本当にわからない
spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
最良の決定です。
Hibernate 20.2.1。キャッシュマッピングドキュメントセクション から引用
デフォルトでは、エンティティは2次キャッシュの一部ではないため、この設定を維持することをお勧めします。ただし、persistence.xmlファイルでshared-cache-mode要素を設定するか、構成でjavax.persistence.sharedCache.modeプロパティを使用して、これをオーバーライドできます。
一方、
ENABLE_SELECTIVE(デフォルトおよび推奨値):エンティティは、明示的にキャッシュ可能としてマークされていない限りキャッシュされません。
したがって、影響を受けるすべてのエンティティに@ javax.persistence.Cacheableまたは@ org.hibernate.annotations.Cacheで注釈を付けていない可能性がありますか?これにより、クエリキャッシュが2番目のレベルキャッシュ内で影響を受けるエンティティを正常に検索しようとし、単一の選択で各エンティティのフェッチを開始するという影響が生じる可能性があります。
追加しましたか
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
キャッシュしたいクラスで?
クラスパスにehcache.xmlファイルが必要です。ファイルには、少なくともデフォルトのキャッシュ戦略が含まれている必要があります。デバッグを簡単にするために、エンティティがキャッシュから削除されないことを確実にすることを永遠にします。
ehcache.xml:
_<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
Name="CacheManager"
maxBytesLocalHeap="250m">
<defaultCache eternal="true"
...
/>
<cache name="org.hibernate.cache.internal.StandardQueryCache"
eternal="true"
...
/>
_
すべてが正常であることを確認するには、アプリケーションの起動中に次のログを取得する必要があります。
_Could not find a specific ehcache configuration for cache named [com.yourcompany.YourClass]; Using defaults.
_
これは、エンティティキャッシュアノテーションが正しく読み取られ、デフォルトのキャッシュが使用されることを意味します。
entityManager.find(Clazz.class, pk)
を使用してテストする場合、クエリキャッシュではなく、エンティティキャッシュのみが関与します。クエリキャッシュは、クエリ(em.createQuery(...)およびリレーションシップに使用されます
また、私はorg.hibernate.cache.ehcache.SingletonEhCacheRegionFactoryを使用しますが、私がより良いとは知りません。
JCache、Ehcache、Gvava Cache、Hazelcast Cache、Caffeine Cacheのうち、サードパーティのキャッシュプロバイダーを使用できます。
Quora のこの回答を参照して、Springブートで2次キャッシュを有効にして構成する方法を確認してください。