Another Hibernate question... :P
Using Hibernate's Annotations framework, I have a User
entity. Each User
can have a collection of friends: a Collection of other User
s. However, I have not been able to figure out how to create a Many-to-Many association within the User
class consisting of a list of User
s (using a user-friends intermediate table).
Here's the User class and its annotations:
@Entity
@Table(name="tbl_users")
public class User {
@Id
@GeneratedValue
@Column(name="uid")
private Integer uid;
...
@ManyToMany(
cascade={CascadeType.PERSIST, CascadeType.MERGE},
targetEntity=org.beans.User.class
)
@JoinTable(
name="tbl_friends",
joinColumns=@JoinColumn(name="personId"),
inverseJoinColumns=@JoinColumn(name="friendId")
)
private List<User> friends;
}
The user-friend mapping table has only two columns, both of which are foreign keys to the uid
column of the tbl_users
table. The two columns are personId
(which should map to the current user), and friendId
(which specifies the id of the current user's friend).
The problem is, the "friends" field keeps coming out null, even though I've pre-populated the friends table such that all the users in the system are friends with all the other users. I've even tried switching the relationship to @OneToMany
, and it still comes out null (though the Hibernate debug output shows a SELECT * FROM tbl_friends WHERE personId = ? AND friendId = ?
query, but nothing else).
Any ideas as to how to populate this list? Thank you!
@ManyToMany to self is rather confusing because the way you'd normally model this differs from the "Hibernate" way. Your problem is you're missing another collection.
Think of it this way - if you're mapping "author" / "book" as many-to-many, you need "authors" collection on Book and "books" collection on Author. In this case, your "User" entity represents both ends of a relationship; so you need "my friends" and "friend of" collections:
@ManyToMany
@JoinTable(name="tbl_friends",
joinColumns=@JoinColumn(name="personId"),
inverseJoinColumns=@JoinColumn(name="friendId")
)
private List<User> friends;
@ManyToMany
@JoinTable(name="tbl_friends",
joinColumns=@JoinColumn(name="friendId"),
inverseJoinColumns=@JoinColumn(name="personId")
)
private List<User> friendOf;
You can still use the same association table, but note that join / inverseJon columns are swapped on collections.
The "friends" and "friendOf" collections may or may not match (depending on whether your "friendship" is always mutual) and you don't have to expose them this way in your API, of course, but that's the way to map it in Hibernate.