2013-02-20 10 views
8

我々のプロジェクトでは、hibernate4ehcacheを使用しています。私たちはほとんど不変オブジェクトを扱うので、キャッシングはアプリケーションにうまく収まる機能です。Hibernate cache:キャッシュされたクエリによって返されたオブジェクトがL2キャッシュに格納されていますか?

@Entity 
@Table(name = "DOGS") 
@Immutable 
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY) 
class Dog { 
    @Id @Column 
    Long id; 
    @Column 
    String name; 
} 

とクエリ:

Criteria criteria = session.createCriteria(Dog.class); 
criteria.add(Restrictions.in("id", ids)); 
criteria.setCacheable(true); 

クエリキャッシュの生存時間に設定され、我々は、以下のエンティティを持っていると仮定すると

:クエリキャッシュを有効にしようとしているが、我々は次のような問題に遭遇しました犬のtimeToLiveの約3/4。それが実行され、返された犬のインスタンスは、セカンドレベルに格納されている、

  1. クエリが初めて呼び出されたとき(ある空のキャッシュを想定):ここでは(私は間違った仮定をしたなら、私を修正してください)シナリオですキャッシュ。また、Dog IDはクエリキャッシュに格納されます。
  2. クエリが2回呼び出されたとき(犬IDがクエリキャッシュにあり、犬オブジェクトがL2キャッシュにある)、すべて正常に機能します。クエリキャッシュはIDを返し、DogはL2からフェッチされます。
  3. クエリキャッシュの有効期限が切れても(ただしL2キャッシュは有効です)、クエリが再実行され、Dog IDがキャッシュされます。
  4. ここで、L2キャッシュはDogオブジェクトで期限切れになり、すべてのオブジェクトがキャッシュから追い出されます。クエリキャッシュにはまだidsがキャッシュされているため、hibernateはDogオブジェクトを1つずつフェッチします。これは永久にかかります

第3のポイントは私を悩ませています。クエリキャッシュが無効化され、データベース上で再実行され、Dogオブジェクトがフェッチされましたが、DogオブジェクトはL2キャッシュで更新されませんでした。クエリはクエリキャッシュ内のdog IDのみを更新し、L2キャッシュは更新しなかったようです。

L2キャッシュにもクエリを強制的に更新する方法はありますか?おそらく、このシナリオは異なる方法で処理されるでしょうか?

+0

「もL2キャッシュを更新するクエリを強制的に」これはあなたの質問に対する解決策だと思いますEHCacheが更新の際にそれを処理するように、キャッシュ・モードを書込みます。 – Phani

+0

エンティティは読み取り専用なので、役立たないでしょう。 –

答えて

1

私はこれを試してみましたが、L2キャッシュ

//clear the cache entity 
sf.getCache().evictEntity(Dog.class,12345); //Entity with 12345 id 

//or clear a collection 
sf.getCache().evictCollection("com.package.Dog.getCol",12345); //Collections 
//Note: the collection contains the name of the fully qualified class. 

//then, run the query 

をきれいにするために、過去に私のために働いたが、それは

+0

いつキャッシュをクリーニングすることをお勧めしますか?すべての要求の前にクリアすると、キャッシュを持つのは意味がありません。 –

+0

スケジュールされたイベントで(プロジェクトの事実により)クリーンなキャッシュを実行しました。 時々(スケジュールされた時間はシステムのチームからのものでした)、キャッシュ – victoriza

+0

をきれいにするので、実際にはプロジェクトのDBサイズと使用方法によって異なります。正確なデータがないと推測することは不可能です。 – victoriza

2
を役に立てば幸い

参照セカンドレベルキャッシュを使用すると、キャッシュされたばかりのために指定し、オブジェクト/ POJOのためのものです。しかし、クエリキャッシュは特定のクエリに対して作成されます。したがって、クエリキャッシュが更新されたときに、2つ目のレベルのキャッシュは更新されません。だから両方の構成が違うのです。 Hibernate Documentationまたはthis linkまたはthis linkのいずれかを参照することで、わかりやすくなる場合があります。

+0

これらは2つの異なるキャッシュであると理解していますが、クエリキャッシュはドメインキャッシュを使用してIDでオブジェクトを取得します。これは説明された問題につながりますが、私はこれまでのところ解決策を見いだせませんでした。 –

+0

したがって、この答えは説明された問題を解決しません。 –

+0

友達にはこのデザインを受け入れる必要があります。これは問題ではなく、これはこのように設計されています。 –

0

私の場合、休止状態で最小のput設定を無効にしてから、SQLが発行されるたびにクエリキャッシュが自動的に関連するすべての第2レベルのキャッシュを更新します。

私は/あなたが読んで有効にすることができます(これもバグ私を長い時間.....)

<property name="hibernate.cache.use_minimal_puts" value="false"/> 
関連する問題