0

ManyToMany を使用してマップされたセットを持つオブジェクトがあります。セットは、数十万の完全なものになる可能性があります。セットにメンバーを追加したい場合、新しいエントリを追加する前に、JPA がセット内のすべてのオブジェクトを引き戻します。

@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(name = "ROOM_USER",
            joinColumns = @JoinColumn(name = "ROOM_ID"),
            inverseJoinColumns = @JoinColumn(name = "USER_ID"))
private Set<User> members;

後でサービスクラスで、次のようにユーザーをセットに追加したい

    room.addMember(user);

リレーションシップは遅延として宣言されているため、ルームで addMember を呼び出すと、プロキシはメンバーのセットをフェッチします。ここでの問題は、セットが大きくなると、メンバーのセットを取得するのにかなりの時間がかかることです。この場合、インデックスは正常に機能しています。mysql でクエリを調べたところ、問題は非常に単純で、ROOM_USER 結合テーブルに行を追加するだけなのに、大量のデータをプルしています。

JPA は、セット全体を引き戻さずにメンバーをセットに追加する方法を定義していますか?

JPA実装にSpringフレームワークとHibernateを使用しているその他のメモ。

4

2 に答える 2

0

簡単な答えはノーです。レイジーコレクションマッピングは、コレクションにアクセスするとすぐに初期化されます。コレクションのサブセットにアクセスするための規定はありません。

一般に、非常に大きなセットは、まさにあなたが見ている理由から、この種のアソシエーションの良い候補ではありません。

ただし、エントリごとの初期化など、追加の遅延マッピングを可能にする非JPA拡張機能があります。これについてはここにもっとあります。

于 2012-10-08T16:34:36.817 に答える
0

私が思いついた解決策は、UserRoom という結合を表す別のオブジェクトを作成することでした。次に、そのテーブルに行を直接追加できる対応するサービスを作成しました。

    @Entity
    @Table("USER_ROOM")
    public class UserRoom {

         @Id
         private Long id;

         @ManyToOne(fetch=FetchType.EAGER)
     @JoinColumn(name="USER_ID")
         private User user;

         @ManyToOne(fetch=FetchType.EAGER)
     @JoinColumn(name="ROOM_ID") 
         private Room room;
}

これが将来誰かに役立つことを願っています。

于 2014-04-11T13:40:35.030 に答える