0

私は多対多の関係で「学生」と「クラス」を持っています。間にリンクテーブルがあります。

次の方法で HQL を使用してすべての学生を取得したい場合は、すべて問題ありません。

Query queryObject = getSession().createQuery("from Student");
return queryObject.list();          

上記のコードでは、3 人の学生がいる場合、3 人の学生のリストを取得します。

ただし、基準を使用する場合は、リンク テーブルに関連付けがない限り問題ありません。

Criteria crit =  getSession().createCriteria(Student.getClass());        
return crit.list();

2 番目のコードでは、リンク テーブルが空の場合にのみ 3 つの結果が得られます。ただし、関連付けを追加すると、6 つの結果が得られます。ログを見ると、Hibernate は複数の選択を生成します。それはどのように可能ですか?

誰かがなぜこれが起こるのか説明できますか? 3 つのレコードを 1 回だけ返すように条件を修正するにはどうすればよいですか?

編集

Student クラスでは、次のようにマッピングしました。

@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(
    name="room_student_rel"
    , joinColumns={
        @JoinColumn(name="id_student")
        }
    , inverseJoinColumns={
        @JoinColumn(name="id_room")
        }
    )
private List<Room> rooms;

部屋(クラス)で、私はこのようにマッピングしました:

@OneToMany(fetch=FetchType.EAGER,  mappedBy="room")
@Fetch(FetchMode.SELECT)
private List<RoomStudent> roomStudents;
4

1 に答える 1

3

私の以前のコメントを拡張すると、FetchType が EAGER に設定されている場合、Hibernate は外部結合を使用して選択しようとします。

次の 2.2.5.5 を参照してください。

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/

これの意味については、こちらを参照してください。

Hibernate Criteria は FetchType.EAGER で子を複数回返します

これで、FetchMode (基準.setFetchMode("assocFiled",FetchMode.LAZY)) を指定して JOIN 以外に設定したりcriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);、重複をフィルタリングするようなものを使用したりすることもできます。

理想的には、エンティティ マッピングで EAGER を回避し、熱心なフェッチが必要な場合は、何らかのヒントを使用して、または FetchProfile を介してエンティティの読み込み時に明示的に有効にし、必要に応じて重複を処理する必要があります。

于 2013-10-17T17:22:38.153 に答える