Strahinja
Strahinja

Reputation: 460

Many to many on the same Entity

I want to create a instagram-like application. So user is supposed to have list of users that follows and also a list of users that are following him.
Here's what i've done so far:

@ManyToMany(cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
})
@JoinTable(name = "following_followers",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "followedby_id")
)
private List<User> followers;

@ManyToMany(cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
})
@JoinTable(name = "following_followers",
        joinColumns = @JoinColumn(name = "followedby_id"),
        inverseJoinColumns = @JoinColumn(name = "user_id")
)
private List<User> following;

I checked this post and I've done it following the good answer over there, but I'm not quite sure does this work.

Upvotes: 1

Views: 3034

Answers (2)

v.ladynev
v.ladynev

Reputation: 19956

When many-to-many association is managed by Hibernate, you can't control the join table following_followers yourself. For example, you can't delete a record from the table using Hibernate.

There are situations for which many-to-many association can be effective, but I am not sure this is your case. For example, imagine how you manage to delete a follower of a user.

You can try another approach: add a separate entity for a following relation

@Enity
class Following {

  @ManyToOne(fetch = FetchType.LAZY)
  User from;

  @ManyToOne(fetch = FetchType.LAZY)
  User to;

}

Also you can add a unique constraint: (from, to) can be suitable.

Upvotes: 1

Muni
Muni

Reputation: 203

This was my solution for your problem. The user class:

@Entity
public class User {

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

    private String name;

    @OneToMany(mappedBy="to")
    private List<Followers> followers;

    @OneToMany(mappedBy="from")
    private List<Followers> following;

    public User() {}

    public User(String name) {
        this.name = name;
    }

}

As you can see the user class has a reference to the users who is following and those who he follows.

@Entity
public class Followers {

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

    @ManyToOne
    @JoinColumn(name="from_user_fk")
    private User from;

    @ManyToOne
    @JoinColumn(name="to_user_fk")
    private User to;

    public Followers() {};

    public Followers(User from, User to) {
        this.from = from;
        this.to = to;
    }
}

The followers class contain the relationship between the two users, of course you might need to add more information to that class like when 'from' started following 'to'.

If you want to get the followers/following of a user you just call the respective getter.

Upvotes: 0

Related Questions