9

かなり一般的だと思う質問がありますが、答えが見つかりません。

GroupとUserの2つのオブジェクトがあります。私のクラスは次のようになります。

class Group
{
  @ManyToMany(fetch = FetchType.EAGER)
  List<User> users;
}

class User
{
  @ManyToMany(fetch = FetchType.EAGER)
  List<Group> groups;
}

ここで、データベースからユーザーを取得しようとすると、すべてのグループが表示され、すべてのグループがすべてのユーザーを表示します。最後に、stackoverflow例外が発生します。

この問題を解決し、双方向の関連付けとリスト内のオブジェクトに到達する機能を維持するにはどうすればよいですか?

4

3 に答える 3

10

双方向アソシエーションの一方の側を、属性(とにかく使用する必要がある)を使用してアソシエーションの所有側にすると、同じ問題が発生しますか?mappedByこのような:

@Entity public class Group {
  ...
  @ManyToMany(fetch = FetchType.EAGER, mappedBy="groups")
  List<User> users;
}

@Entity public class User {
  ...
  @ManyToMany(fetch = FetchType.EAGER)
  List<Group> groups;
}

更新:EAGER双方向アソシエーションの両側でフェッチを使用することが禁止されており、AFAIKであるという証拠は見つかりません。そのような制限については、HibernateのドキュメントやJPA仕様に記載されていません。

実際、Emmanuel Bernardからの(どういうわけか似たような)問題へのこのコメントによると:

LAZYまたはEAGER、コードベースの無限ループの問題に直交する必要があります。Hibernateは巡回グラフの処理方法を知っています

私にとって、上記はかなり明確です。Hibernateは(コメントで述べたように)マッピングを処理できるはずであり、矛盾する動作をバグと見なしたくなるでしょう。

問題を再現できるテストケースを提供できれば、問題を開くことをお勧めします。

于 2010-10-20T14:26:32.273 に答える
0

Hibernateは、必要なものすべてを熱心にフェッチしようとすると問題なく動作します。オブジェクトのモデリングでは、ループやスタックオーバーフローの例外が発生しないように休止状態を考慮する必要があります。

私がしたことは、関係の片側を削除することです。その側を削除するか、そのままにして反対側を所有者として定義するかを決定できます。また、その側から熱心なフェッチを削除する必要があります。

hibernateが、多対多の関係でフェッチの深さを定義するためのメカニズムを提供できれば、それは素晴らしいことです。

于 2010-10-28T09:51:29.957 に答える
0

熱心なフェッチを制限するために、プロパティ「hibernate.max_fetch_depth」を3のようなものに設定することをお勧めします。

于 2011-01-05T09:33:09.303 に答える