Jack
Jack

Reputation: 6600

how to make a friend relationship?Why does hibernate create a new table for ManyToMany relationship

I need to have a friendship relationship, each user can have zero to many friends.

I am not sure if it is a correct way of doing this and why hibernate is creating the third table, I suppose the foreign keys would be suffecient to make the relationship.

How can I get rid of the third table? In database a table is generated for User,another one is Friend table and the last one is called User_Friend which has User_id, friends_requester_id, friends_receiver_id fields.

The main issue here is every user can be in user_friend relationship without being part of a friendship. For example

User_id friends_requester_id friends_receiver_id
1            1                  2
2            1                  2
3            1                  2    <<<this one is incorrect, 
                                        user id 3 is not part of this friendship record

My classes are as following, I need to know who made the request and at what date the relationship has begun.

@Entity
public class User{
   @Id
   @GeneratedValue
   long id;
   @ManyToMany(cascade = CascadeType.ALL)
   List<Friend> friends;
   ..
}

@Entity
public class Friend implements Serializable {
   @Id
   @ManyToOne
   User friendRequester;
   @Id
   @ManyToOne
   User friendReceiver;
   @Temporal(javax.persistence.TemporalType.DATE)
   Date date;
   ..

}

Upvotes: 1

Views: 1557

Answers (1)

JB Nizet
JB Nizet

Reputation: 691635

You told Hibernate it's a ManyToMany association.

So a user has to be able to have several friends (this rules out a foreign key in the user table), and a friend has to be able to have many users (this rules out a foreign key in the friend table). The only way is thus to have a join table for the association.

If what you actually want is for the user to be able to be the requester of several friends, and also to be the receiver of multiple friends, then you don't want a many-to-many association. What you want is 2 one-to-many associations, that are the inverse side of the many-to-one associations you already have in Friend:

public class User {
    // ...

    @OneToMany(mappedBy = "friendRequester")
    private Set<Friend> requestedFriends;

    @OneToMany(mappedBy = "friendReceiver")
    private Set<Friend> receivedFriends;
}

By the way, I would rename Friend to Friendship, as an instance of Friend is not a friend, but an association between two users who are friends.

Upvotes: 2

Related Questions