2017-12-08 4 views
1

最近私のJavaアプリケーションをhibernate 4.1からhibernate 5.2にアップグレードし、2番目のレベルのエンティティキャッシュの使用に違いがあることに気付きました。キャッシュは、以前のバージョンと同じくらい頻繁に使用されることはありません。2番目のレベルのキャッシュエンティティのハイバーネーションでの使用5.2

物事を単純化するために、私は非常に基本的なモデルを持っているとしましょう:親との関係が1対1のCHILDエンティティ。 PARENTクラスには@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)という注釈が付けられています。 CHILDの多対一の関係には@Fetch(FetchMode.SELECT)という注釈が付けられています。これにより、CHILDをフェッチするときに第2レベルのキャッシュがPARENTを格納する機会が与えられるはずです。

1つのCHILDインスタンス(from CHILD where id=:idのようなクエリを使用)をロードすると、PARENTキャッシュが使用されていることがわかります。クエリを再度実行すると、PARENTセカンダリセレクトはデータベースに繰り返されません。

ただし、複数のCHILDを一度にロードすると(from CHILDのようなクエリで)、PARENTキャッシュは使用されません。もう一度クエリを実行すると、セカンダリのPARENTセレクトが繰り返されます。

これはパフォーマンスの大きな損失です。誰も同じ問題に遭遇しましたか?いくつかの構成部分が欠けていますか?

ありがとうございました。

答えて

1

私はこの問題にもっと時間を費やした後、多くのCHILDを読み込む前に実行されたネイティブクエリが原因であることを発見しました。このネイティブクエリは、データベースセッション(SET LOCAL TIME ZONE '<TIMEZONEID>')のパラメータを設定します。このパラメータは、ユーザーのタイムゾーン内の日付を計算するために使用されます。

読み取りCHILDsメソッドには@Transactional(readOnly = true)が注釈されていますが、セッションでタイムゾーンパラメータを設定すると、エンティティは変更されませんが、query.executeUpdate()を呼び出す必要があります。これは、キャッシュにエンティティの格納を停止させる原因となっているようです。

私はまだ回避策を探していますが、特定の休止状態のバージョンに関係なく、1対複数のCHILDを一度に読むことはありません。

+0

キャッシュの無効化を防ぐにはhttps://stackoverflow.com/questions/19054673/2nd-level-cache-invalidation-with-native-queriesを参照してください。 – JDM

関連する問題