10

このシナリオを検討してください。

  • 休止状態で親エンティティをロードしました
  • 親には、大きくて遅延ロードされた子のコレクションが含まれています
  • ユーザーが親データを表示している間、この初期ロード後にHibernateセッションは閉じられます
  • ユーザーは、怠惰な子供コレクションのコンテンツを表示することを選択できます
  • そのコレクションをロードしたい

このコレクションをロードする方法/最良の方法は何ですか?

  • Childrenコレクションのフェッチは、ユーザーが親を表示し、子を表示することを決定した後にのみ発生するため、セッションインビューはオプションではないと想定します。
  • これは、Webおよびデスクトップベースのクライアントからリモートでアクセスされるサービスです。

ありがとう。

4

3 に答える 3

10

遅延コレクションは、Hibernate.initialize(parent.getCollection()) を使用してロードできますが、親オブジェクトをアクティブなセッションにアタッチする必要があります。

このソリューションは、親エンティティと遅延読み込みフィールドの名前を取得し、コレクションが完全に読み込まれたエンティティを返します。

残念ながら、新しく開いたセッションに親を再アタッチする必要があるため、レイジー コレクションへの参照を使用することはできません。これはエンティティのデタッチされたバージョンを参照するためです。したがって、fieldName とリフレクションです。同じ理由で、これは添付された親エンティティを返さなければなりません。

したがって、OP シナリオでは、ユーザーが遅延コレクションを表示することを選択したときに、この呼び出しを行うことができます。

Parent parentWithChildren = dao.initialize(parent,"lazyCollectionName");

メソッド:

public Entity initialize(Entity detachedParent,String fieldName) {
    // ...open a hibernate session...
    // reattaches parent to session
    Entity reattachedParent = (Entity) session.merge(detachedParent); 

    // get the field from the entity and initialize it
    Field fieldToInitialize = detachedParent.getClass().getDeclaredField(fieldName);
    fieldToInitialize.setAccessible(true);
    Object objectToInitialize = fieldToInitialize.get(reattachedParent);

    Hibernate.initialize(objectToInitialize);
    return reattachedParent;
}
于 2009-07-01T14:35:29.397 に答える
3

ユーザーが見ているものについていくつかの仮定を立てていますが、ユーザーがすでに親を表示していて、本当に子を見たい場合にのみ、子を取得したいようです。

新しいセッションを開いて、親によって子を取得してみませんか? ...の線に沿った何か

criteria = session.createCriteria(Child.class);
criteria.add(Restrictions.eq("parent", parent));
List<Child> children = criteria.list();
于 2009-07-01T14:20:23.297 に答える
0

Hibernate は、通常のフィールドとは異なる方法でコレクションを処理します。

私の仕事では、ケースバイケースで必要な初期ロードでフィールドを初期化するだけで、これを回避しています。たとえば、トランザクションに囲まれたファサード ロード メソッドでは、次のようになります。

public Parent loadParentWithIntent1(Long parentId)
{
  Parent parent = loadParentFromDAO();

  for (Child c : parent.getChildren())
  {
    c.getField1();
  }
}

そして、インテントごとに異なるファサード呼び出しがあります。これらの特定のフィールドが何らかの方法で必要なときにロードされ、ロード時にセッションに配置されるため、これは基本的に必要なものを実現します。

于 2009-07-01T14:36:31.940 に答える