0

「ユーザーAがユーザーBをフォローしている」、「ユーザーAがユーザーBの友達になりたい」など、ユーザーとユーザーの関係を設計しようとしています。

Userクラスがあり、その設計方法は次のようになります。

@Entity
public class User{
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> followers;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> following;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> friendRequests;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> requesting;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> friends;

}

私は2つの問題に直面しています:

  • Hibernateは、複数のバッグを同時にフェッチできないという問題を私に与えています
  • オンラインで調べたところ、FetchType.EAGERを削除するか、ListではなくSetに変更すると言われましたが、Fieldにデフォルト値がありません。

関係が適切に定義されていないように感じます。また、現在、UserテーブルとUser_Userテーブルしか表示されていないため、さらに多くのテーブルが表示されるはずです。


アップデート

以下は、3つのテーブル、友達、フォロワー、およびリクエスターを作成します。これは5つのテーブルと比較していくらか最適化されていますか?そして、J4mes氏が提案したものと比較して、これに何か利点はありますか?

@ManyToMany
@JoinTable(name = "followers", joinColumns = @JoinColumn(name = "followerId"), inverseJoinColumns = @JoinColumn(name = "userId"))
private List<User> followers;
@ManyToMany
@JoinTable(name = "followers", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "followerId"))
private List<User> following;
@ManyToMany
@JoinTable(name = "friends", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "friendId"))
private List<User> friends;
@ManyToMany
@JoinTable(name = "requesters", joinColumns = @JoinColumn(name = "requesterId"), inverseJoinColumns = @JoinColumn(name = "userId"))
private List<User> friendRequests;
@ManyToMany
@JoinTable(name = "requesters", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "requesterId"))
private List<User> requesting;
4

3 に答える 3

1

まず、機能を実装するには、@ManyToManyの代わりにを使用する必要があり@OneToManyます。次のようになります。

@Entity
public class User implements Serializable {
   @ManyToMany(mappedBy="followers")
   @JoinTable(name="followingTable")
   private Set<User> following;
   @ManyToMany
   @JoinTable(name="followerTable")
   private Set<User> followers;
   @ManyToMany(mappedBy="friendRequests")
   @JoinTable(name="requestingTable")
   private Set<User> requesting;
   @ManyToMany
   @JoinTable(name="friendRequestTable")
   private Set<User> friendRequests;
   @ManyToMany
   private Set<User> friends;
}

あなたの関係は私には双方向の関係のように見えます。を使用する場合@OneToMany、それはC has 2 followers A and B=を意味しA and B only follows Cます。しかし、実際には、一人が多くの人をフォローすることができ、一人が多くの人をフォローすることができます。言い換えれば、A and B can also follow D

その上、あなたはまったく使うべきではありませんcascadeType.ALL。このカスケードポリシーは、1人のユーザーが自分のアカウントを削除し、データベース内の対応するエントリを削除すると、そのユーザーの友達などもすべて削除されることを意味します。

于 2012-01-12T05:37:45.003 に答える
0

基本的にへの参照であるすべての彼にマップする少なくとも2つの列を持つテーブルを作成しようとするUserからを分離しますFriendsUser_IDFriends_IDsUser_ID

また、最初に呼び出すとすぐにすべてEAGERのデータが読み込まれます。すべてのユーザーとその友達をロードすることを意味します。友達を読み込むには、つまり、必要なときにだけ読み込む必要があります。LAZY

于 2012-01-12T05:31:35.403 に答える
0

Hibernateはユーザーエンティティに対して1つのテーブルのみを生成し、ユーザーとユーザーの関係の相互参照テーブルを想定しています。異なるテーブルを使用するための回避策は、異なる関係に対して異なるエンティティを設定することです。

ユーザーエンティティ

@OneToMany
List<Follower> followers;

フォロワーエンティティ

@Entity
class Follower
...
@ManyToOne
User user;

@Id
@Generated
int id;

EAGERフェッチに関しては、データベースの設定方法によっては、これらの熱心なロードはすべて非常に高額になる可能性があるため、実際にはすべてをLAZYにする必要があります。ユーザーがユーザーフォロワーをロードしたい場合にのみ、それらをフェッチしたいと思います。

于 2012-01-12T05:20:04.667 に答える