3

休止状態のエンティティを ehcache に保存しています。エンティティを取得するためにファサード レイヤーが呼び出されると、インターセプターがそのメソッドを呼び出してキャッシュします。次に同じメソッドが呼び出されると、キャッシュからエンティティが返されます。これはすべてうまくいきます。

私のエンティティには、FetchType.Lazy として定義されているいくつかのプロパティ (オブジェクトまたは関連付けられたエンティティ) があります。このようなもの、

@JoinColumn(name = "inventory_item_oid", referencedColumnName = "inventory_item_oid")
@ManyToOne(fetch = FetchType.LAZY)
private InventoryItem inventoryItem;

したがって、すべてのプロパティが読み込まれるわけではありません。インベントリ アイテムが必要な場合に呼び出されます。この呼び出しは、LazyInitialization 例外をスローしています。

キャッシュされた値は 1 日有効であるため、有効期限が切れる前に何度でも呼び出すことができます。

上記の例外をスローするこれらの呼び出しの 1 つ。

長い休止状態セッションを使用すると、この問題を解決できることがわかりました。しかし、私のものはリクエスト/レスポンスベースのアプリケーションであるため、機能しません。

プロパティにアクセスする前に InventoryItem が null かどうかを確認する必要があるもう 1 つの方法があります。null の場合は、その値を個別に取得して親にアタッチする必要があります。これは良いように思えます...しかし、私は多くのエンティティを持っているので、多くの作業が必要です.

レイジーとして定義されたオブジェクトを取得できる他の方法があるかどうかを知りたいです。

4

1 に答える 1

1

EHCache にエンティティを自分でキャッシュしないでください。代わりに、2 番目のレベルのキャッシュを使用するように Hibernate を構成し、その実装として EHCache を使用する必要があります。

最終結果は同じになります。エンティティがキャッシュされ、ラウンドトリップがデータベースに保存されます。しかし、第 2 レベルのキャッシュを使用すると、すべてが透過的になります。セッションからエンティティをロードすると、Hibernate がそれらを自動的にキャッシュに保存します。セッションからそれらをリロードすると、Hibernate はキャッシュからそれらを取得します。また、エンティティを更新すると、キャッシュから削除され、次回は新しいコピーがリロードされるようになります。

手作りのソリューションとのもう 1 つの大きな違いは、Hibernate がアタッチされたエンティティを返すことです。そのため、単に cachedEntity.getNonCachedEntity() を呼び出すと、Hibernate は、キャッシュがまったくない場合とまったく同じように、キャッシュされていないエンティティを遅延ロードします。

エンティティがデータベースから取得されるか、2 番目のレベルのキャッシュから取得されるかにかかわらず、何も変更されません。属性が遅延読み込みされ、セッションが閉じられた後にこの属性がアクセスされる場合、セッションの前に遅延属性を初期化する必要があります。閉じています。

呼び出しHibernate.initialize(foo.getInventotyItem())て初期化します。

詳細については、Hibernate のドキュメントを参照してください。

于 2012-06-06T21:14:28.033 に答える