プロジェクトではhibernate4とehcacheを使用しています。私たちは主に不変オブジェクトに取り組んでいるため、キャッシングは私たちのアプリケーションにうまく適合する機能です。クエリ キャッシュを有効にしようとしたときに、次の問題が発生しました。
次のエンティティがあると仮定します。
@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 は、Dog の timeToLive の約 3/4 に設定されています。シナリオは次のとおりです(間違った仮定をした場合は修正してください):
- クエリが初めて呼び出されると (キャッシュが空の場合)、クエリが実行され、返された Dog インスタンスが第 2 レベルのキャッシュに格納されます。また、Dog ID はクエリ キャッシュに格納されます。
- クエリが 2 回目に呼び出されると (Dog ID はクエリ キャッシュにあり、Dog オブジェクトは L2 キャッシュにあります)、すべて正常に動作します。クエリ キャッシュは ID を返し、Dog は L2 からフェッチされます。
- クエリ キャッシュの有効期限が切れると (ただし、L2 キャッシュは引き続き有効です)、クエリが再実行され、Dog ID がキャッシュされます。
- これで、Dog オブジェクトの L2 キャッシュが期限切れになり、すべてのオブジェクトがキャッシュから削除されます。クエリ キャッシュにはまだ ID がキャッシュされているため、hibernate は Dog オブジェクトを 1 つずつフェッチしますが、これには時間がかかります。
3番目のポイントは私を悩ませています。クエリ キャッシュが無効になり、データベースで再実行され、Dog オブジェクトがフェッチされましたが、L2 キャッシュで Dog オブジェクトが更新されませんでした。クエリはクエリ キャッシュ内の犬の ID のみを更新し、L2 キャッシュは更新しなかったようです。
クエリで L2 キャッシュも強制的に更新する方法はありますか? おそらく、このシナリオは別の方法で処理されるのでしょうか?