1

エンティティマネージャーの実装で Hibernate 4.1.4 を使用しており、非常に満足しています。単一のエンティティまたはエンティティの小さなセット (10 ~ 50 + サブエンティティ) を読み込むと、優れたパフォーマンスが得られ、すべての結合がうまく機能し、双方向です。編集・保存・削除がカンタン!

レポート用に 2500 のエンティティと関連データを読み込み中

サブエンティティとともに数百または数千のエンティティをロードしようとすると、問題が発生します。1 つの例では、2 つの 1 対 1 結合と 3 つの 1 対多結合と共に、約 2500 の基本エンティティがあります。これにより、2500 x 5 +1 クエリが発生します。データベース (DB2) での実行には約 30 秒かかります。

動的クエリとエンティティ マネージャー create query メソッドを使用します。

http://docs.jboss.org/hibernate/orm/4.1/javadocs/

http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html

結合を使用するように Hibernate を誘導しようとしています

私たちの観察では、何を試しても、プライマリ クエリの結合としてサブエンティティのロードを実行するために hibernate を取得できないようです。find メソッドを使用して単一のエンティティをロードし、主キーによって hibernate は結合を使用しますが、複数の基本エンティティがロードされている場合は使用しません。

同じ結果で基準APIを試しました。

クエリで複数のエンティティを取得することに成功

例:

select a,b from table1 a left join table2 b

クエリで手動で結合を行い、タプルを介して個々のエンティティを取得することに部分的に成功しましたが、これは注釈付きのエンティティ モデルをバイパスし、推奨される方法ではありません (回避できる場合)。

http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#objectstate-querying-executing

タプルで遭遇した問題は、タプルがプライマリ エンティティから切り離されており (注釈付きの関係を介して読み込まれていないため、これは論理的と思われます)、それらを再アタッチする方法がないように思われることです。エンティティのリストに 1 対多のすべてのレコードを手動で追加した後、hibernate がリストの get メソッドにヒットすると、リストのイーガー/レイジー ロードを試行します (リストが既に設定されているにもかかわらず)。

試行された最適化 - データセットのプリロード

私たちが試みたもう 1 つの最適化手法は、事前にデータ セットをプリロードすることでした。すべてのコア エンティティをロードした後、pk のリストを作成し、単一のクエリを起動して、1 対多のデー​​タ セットをすべてロードしました。しかし、hibernate がリスト データのゲッターにヒットすると、セッションで既にプリロードされているものを無視して、リストを熱心/遅延ロードしようとします (おそらくキャッシュを有効にする必要がありますか?)。

提案?

私たちは多くの異なる方向に進んでいますが、ほとんど成功していません。誰かが正しい道を示してくれることを期待しています (または新しい道を示してください!)。

4

1 に答える 1

1

自分で決めたようです!2 つの方法で問題を解決しました。

  1. クエリの Join fetch は、1 対多の結合を処理します。もちろん、Hibernate は複数のバッグを同時にフェッチできないという例外をスローするため、結合フェッチは 1 つしか実行できません。

    例:

    LEFT OUTER JOIN FETCH t.table3 t3
    
  2. 追加の結合については、 @Fetch(FetchMode.SUBSELECT) がうまくいきました!

クエリの総数を数千から数に効果的に減らしました。一例では、188 のコア エンティティが選択され、合計 12 のクエリが実行されました。追加のクエリは、ほとんどが 1 対 1 のルックアップであり、合計実行時間 (平均 1 ~ 2 秒) に大きな影響はありません。188 レコードまたは 1888 レコードのどちらが選択されても、クエリの総数は大幅に増加しません。

詳しい情報が必要な場合は、お気軽に私に連絡するか、コメントを残してください。:)

于 2012-07-15T20:34:03.083 に答える