2012-03-22 4 views
2

私は、Hibernateデータアクセスレイヤーがインメモリオブジェクトキャッシュの背後に座っています。クライアントサイドのキャッシュミスの場合、インメモリキャッシュは、オブジェクトグラフをキャッシュにロードするためにHibernateレイヤーを呼び出します。オブジェクトがキャッシュにどのようにシリアライズされるかによって、Hibernateからオブジェクトグラフ全体を一度にロードする必要があります(つまりレイジーロードはありません)。このようなシナリオは、Hibernateのドキュメントhereでカバーされています。ここでの抜粋です。Hibernate.initialize()がレイジーロードされたコレクションで動作しないようです

個別のビジネス層を備えたアプリケーションでは、ビジネスロジックはWeb層が戻る前に、必要なすべてのコレクション「準備」しなければなりません。つまり、ビジネス層はすべてのデータをロードして、特定のユースケースに必要なプレゼンテーション/ Web層に既に初期化されているすべてのデータを返す必要があります。通常、アプリケーションは、Web層に必要な各コレクション(この呼び出しは、セッションが閉じられる前に行わなければなりません)に対してHibernate.initialize()を呼び出すか、FETCH句またはFetchMode.JOINを使用してHibernateクエリを使用して賢くコレクションを取得します基準で。これは、セッションファサードの代わりにコマンドパターンを採用する方が簡単です。

私はちょうど私が私がちょうどデフォルトレイジーローディング動作を維持し、その後に各コレクションにHibernate.initialize()を行うと考えました(this StackOverflowの質問に記載されているように、私はMultipleBagFetchExceptionで終わる)、直接私のエンティティにフェッチイーガーを有効にすることはできませんので、その物体を完全に飽和させるようにする。問題は、私のコレクションがまだ空になることです。

私のユニットテストでは、この戦略はうまく機能しているようです(私のオブジェクトは適切に飽和しています)が、このHibernateレイヤーをインメモリキャッシュにプラグインとして実行すると私のDALはメモリ内のキャッシュがキャッシュミスのために呼び出すことになります)私は説明された動作を見ています。

現在、私は

<property name="current_session_context_class">thread</property> 

と私のセッションを処理し、その後、私は、負荷へのオブジェクトのための私のセッションの取得を行うた後、私のDAOで

sessionFactory.getCurrentSession(); 

を呼んでいます。私のセッション処理は、私の作業ユニットテストと非動作DAOの両方で同じことが分かります。ここで何が起こっているかについての提案。さらに詳しい情報が必要なら私に知らせてください。

答えて

1

私は答えを見つけたが、私のOPが暗示するように、それが本当になって回収不良の初期化に関連していないですが、私はそれが誰かを助けるかもしれないことを期待して、とにかくそれをここに投稿します:

問題はUUIDの(渡されたということでしたここで重要ではない良い理由のためにサービス層全体の文字列として)私がオブジェクトを識別するために使用していたのは、大文字でUUID文字列を送信している間に小文字でクライアント側に送られていました。明らかに、DBはこの違いを気にせず、どちらの場合でも少なくともグラフのルートレベルのオブジェクトを返すことができましたが、ルートレベルオブジェクトの小文字のUUID識別子文字列を指定すると、コレクションを飽和させる後続の結合は失敗しました。なぜ誰がこのことが分かっているのですか? Hibernateが生成したSQLは、UUIDの大文字小文字の区別にかかわらず正しい結果を返すように見えますが、HibernateはUUID識別子が技術的に一致しないため、最終的にいくつかの結合結果を取り除きました。

1

私はこれも時々起こるのを見たことがあり、その答えを知りたいのは興味深いでしょう。回避策として、私は子供を初期化するために、2つの異なる方法を使用しました:

  1. そのコレクションは、parent.getChildCollection().size()

者がいるように見える協会にFetchMode.JOINCriteriaクエリを使用を呼び出す場合常に働く。

関連する問題