19.3. キャッシュの管理
オブジェクトを
save()
、update()
、saveOrUpdate()
に渡すとき、そして load()
、get()
、list()
、 iterate()
、scroll()
を使ってオブジェクトを取得するときには常に、そのオブジェクトは Session
の内部キャッシュに追加されます。
次に
flush()
が呼ばれると、オブジェクトの状態はデータベースと同期化されます。この同期が起こることを望まないときや、膨大な数のオブジェクトを処理していてメモリを効率的に扱う必要があるときは、evict()
メソッドを使って一次キャッシュからオブジェクトやコレクションを削除することが出来ます。
ScrollableResults cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set while ( cats.next() ) { Cat cat = (Cat) cats.get(0); doSomethingWithACat(cat); sess.evict(cat); }
Session
はインスタンスがセッションキャッシュに含まれるかどうかを判断するための contains()
メソッドも提供します。
すべてのオブジェクトをセッションキャッシュから完全に取り除くには、
Session.clear()
を呼び出してください。
二次キャッシュのために、
SessionFactory
にはインスタンス、クラス全体、コレクションのインスタンス、コレクション全体をキャッシュから削除するためのメソッドがそれぞれ定義されています。
sessionFactory.evict(Cat.class, catId); //evict a particular Cat sessionFactory.evict(Cat.class); //evict all Cats sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
注記
SessionFactory.evictXXX(..., Serializable id) APIを使い、アプリケーションの結果として、このメソッドが呼び出されます。この API を使ったアプリケーションは、これに対する呼び出しにより、他のトランザクションがJBoss Cache ベースの二次キャッシュで完了するまで待機させないようにしてしまう可能性があると認識しているはずです。
さらに、トランザクションの最中で発生した呼び出しは、トランザクションがコミットするまでロックを保持しますが、他のノードをアップデートしません。これが問題な場合は、トランザクション開始前、かつコミット前にエビクションを行うと便利でしょう。
CacheMode
は特定のセッションが二次キャッシュとどのように相互作用するかを制御します。
CacheMode.NORMAL
:アイテムの読み込みと書き込みで二次キャッシュを使いますCacheMode.GET
:読み込みは二次キャッシュから行いますが、データを更新した場合を除いて二次キャッシュに書き込みをしません。CacheMode.PUT
:二次キャッシュにアイテムを書き込みますが、読み込みには二次キャッシュを使いません。CacheMode.REFRESH
:二次キャッシュにアイテムを書き込みますが、読み込みには二次キャッシュを使いません。hibernate.cache.use_minimal_puts
の影響を受けずに、データベースから読み込むすべてのアイテムの二次キャッシュを強制的にリフレッシュします。
二次キャッシュの内容やクエリキャッシュ領域を見るために、
Statistics
API を使ってください:
Map cacheEntries = sessionFactory.getStatistics() .getSecondLevelCacheStatistics(regionName) .getEntries();
統計情報を有効にして、さらにオプションとして、キャッシュエントリをより読解可能な形式で保持することを Hibernate に強制する必要があります:
hibernate.generate_statistics true hibernate.cache.use_structured_entries true