I am trying to design some kind of user to user relationship, such as "user A follows user B" and "User A wants to be User B's friend".
I have a User class, and the way it is designed looks like this:
@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; } I am running into two problems:
- Hibernate is giving me cannot simultaneously fetch multiple bags problem
- I have looked up online, people said to remove FetchType.EAGER or change it to Set instead of List, but that resulted me Field doesn't have a default value
I have a feeling that the relationship is not defined properly, and also I should be seeing more tables, because right now, I only see User table, and User_User table.
Update
The following creates 3 table, friends, followers, and requesters. Is this somewhat optimized compared to 5 tables? And are there any advantage to this in comparison with what Mr.J4mes suggested?
@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;