CeccoCQ
CeccoCQ

Reputation: 3754

JPA One To Many/Many To Many Example

I'm using:

I have to create an application that allows user to make friendship.

I'm still in design phase, and I would like to have these tables:

- User {_id, name, address} 
 - Friendship {idUserA, idUserB, date}

For my purpose I should have a mutual relationship from Users. For example 1 is friend of 2 and indirectly 2 is friend of 1. So in my table I think to have:

Friendship = {1, 2, ...}

I'm asking how I can simulate this behaviour. I've read his topic: Many-to-many on the same table with additional columns and I've followed this instruction generating database tables from entity (property of hibernate). But in this example when I load my Friend A, I've a list with Friend B and when I load B I haven't user A into List.

How I can implement this damn mutual relationship?

Upvotes: 1

Views: 5536

Answers (2)

huzeyfe
huzeyfe

Reputation: 3704

Actually I am not big fan of OneToMany and especially ManyToMany relationships. I prefer having another table like Friendship as you did. So as far as I understand you are mixing to approaches. To me simplest way is having a Friendship Table and all you need in this table is match two friends so design could be:

@Entity
public class User{

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @Column
    private String name;

    @Column
    private String address;

}

@Entity
public class Friendship {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @ManyToOne 
    @JoinColumn(name="friend_requester_id")
    private User friendRequester;

    @ManyToOne 
    @JoinColumn(name="friend_accepter_id")
    private User friendAccepter;

    private Date date;

}

When listing friends either you could list friendships -as they are another table- or friends using this table. However it is a bit tricky If you would like to list only friends but not so hard. You could have a getFriends(List<Friendship> friendships, int userId) method and list friends like:

  List<User> friends ...

  Iterator iterator = friendships.iterator();
  while (iterator.hasNext()) {
     Friendship friendship = (Friendship) iterator.next();
     if (friendship.getFriendRequester().getId != userId) {
         friends.add(friendship.getFriendRequester);
     } else {
         friends.add(friendship.getFriendAccepter);
     }
  }

  return friends;

Another advantage of this implementation you can differentiate who requested to be a friend later (if it is needed).

In my opinion, yes it seems to be complicated and overworked but it is fairly maintainable and less painful.

Upvotes: 0

magomi
magomi

Reputation: 6685

As far as I understand this sample the mutuality is not implicit. To have friendship relation from A->B and from B->A you have to either add two entries into your table or you have to implement two sets and return an intersection of the two list:

@OneToMany(mappedBy="myFriends")
private List<MyFriends> myFriends;

@OneToMany(mappedBy="me")
private List<MyFriends> iAmFriendOf;

...

Set<MyFriends> getFriends() {
    Set<MyFriends> friends = new HashSet<MyFriends>();
    friends.addAll(myFriends);
    friends.addAll(iAmFriendOf);
    return friends;
}

Upvotes: 1

Related Questions