I have a class User. A user can be a friend with many other users. The relationship is mutual. If A is a friend of B then B is a friend of A. Also I want every relation to store additional data - for example the date when two users became friends. So this is a many-to-many relationship on the same table with additional columns. I know that a middle class Friendship should be created(containing two user ids and column for the date). But I am coming short at mapping this with Hibernate. The thing that stops me is that the mapping is to the same table. I can solve it, if the many-to-many relationship was between two different tables.
我有一个类用户。用户可以是许多其他用户的朋友。关系是相互的。如果A是B的朋友,那么B是A的朋友。我还希望每个关系都能存储额外的数据——例如两个用户成为朋友的日期。这是同一个表上的多对多关系,还有其他列。我知道应该创建一个中产阶级友谊(包含两个用户id和日期列)。但是我在用Hibernate映射这个方面做得不够。阻止我的是映射到同一个表。我可以解它,如果多对多关系在两个不同的表之间。
3 个解决方案
#1
7
You have said
你说
many-to-many relationship on the same table
在同一个表上多对多关系。
It is not a good idea. It is a nightmare to maintain.
这不是一个好主意。这是一场噩梦。
Try this one instead
试试这个相反
@Entity
public class Friend {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer friendId;
@Column
private String name;
@OneToMany(mappedBy="me")
private List<MyFriends> myFriends;
}
@Entity
public class MyFriends {
@EmbeddedId
private MyFriendsId id;
@Column
private String additionalColumn;
@ManyToOne
@JoinColumn(name="ME_ID", insertable=false, updateable=false)
private Friend me;
@ManyToOne
@JoinColumn(name="MY_FRIEND_ID", insertable=false, updateable=false)
private Friend myFriend;
@Embeddable
public static class MyFriendsId implements Serializable {
@Column(name="ME_ID", nullable=false, updateable=false)
private Integer meId;
@Column(name="MY_FRIEND_ID", nullable=false, updateable=false)
private Integer myFriendId;
public boolean equals(Object o) {
if(o == null)
return false;
if(!(o instanceof MyFriendsId))
return false;
MyFriendsId other = (MyFriendsId) o;
if(!(other.getMeId().equals(getMeId()))
return false;
if(!(other.getMyFriendId().equals(getMyFriendId()))
return false;
return true;
}
public int hashcode() {
// hashcode impl
}
}
}
regards,
问候,
#2
2
I'm not sure this will fit your case, but give it a try.
我不敢肯定这是否适合你的情况,但不妨一试。
@Entity
public class Friend {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int friendId;
@Column
private String name;
@ManyToMany(mappedBy="owner")
private List<Friendship> friendships;
}
@Entity
public class Friendship {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int friendshipId;
@OneToOne
private Friend owner;
@OneToOne
private Friend target;
// other info
}
#3
1
I had the same problem. You can try something like this:
我遇到了同样的问题。你可以试试这样的方法:
<class name="Friend" entity-name="RelatedFriend" table="FRIENDS">
<id name="id" type="long">
<generator class="native" />
</id>
<!-- *** -->
<set name="relatedFriends" table="RELATED_FRIENDS">
<key column="FRIEND_ID" />
<many-to-many column="RELATED_FRIEND_ID" class="Friend" entity-name="RelatedFriend"/>
</set>
</class>
#1
7
You have said
你说
many-to-many relationship on the same table
在同一个表上多对多关系。
It is not a good idea. It is a nightmare to maintain.
这不是一个好主意。这是一场噩梦。
Try this one instead
试试这个相反
@Entity
public class Friend {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer friendId;
@Column
private String name;
@OneToMany(mappedBy="me")
private List<MyFriends> myFriends;
}
@Entity
public class MyFriends {
@EmbeddedId
private MyFriendsId id;
@Column
private String additionalColumn;
@ManyToOne
@JoinColumn(name="ME_ID", insertable=false, updateable=false)
private Friend me;
@ManyToOne
@JoinColumn(name="MY_FRIEND_ID", insertable=false, updateable=false)
private Friend myFriend;
@Embeddable
public static class MyFriendsId implements Serializable {
@Column(name="ME_ID", nullable=false, updateable=false)
private Integer meId;
@Column(name="MY_FRIEND_ID", nullable=false, updateable=false)
private Integer myFriendId;
public boolean equals(Object o) {
if(o == null)
return false;
if(!(o instanceof MyFriendsId))
return false;
MyFriendsId other = (MyFriendsId) o;
if(!(other.getMeId().equals(getMeId()))
return false;
if(!(other.getMyFriendId().equals(getMyFriendId()))
return false;
return true;
}
public int hashcode() {
// hashcode impl
}
}
}
regards,
问候,
#2
2
I'm not sure this will fit your case, but give it a try.
我不敢肯定这是否适合你的情况,但不妨一试。
@Entity
public class Friend {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int friendId;
@Column
private String name;
@ManyToMany(mappedBy="owner")
private List<Friendship> friendships;
}
@Entity
public class Friendship {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int friendshipId;
@OneToOne
private Friend owner;
@OneToOne
private Friend target;
// other info
}
#3
1
I had the same problem. You can try something like this:
我遇到了同样的问题。你可以试试这样的方法:
<class name="Friend" entity-name="RelatedFriend" table="FRIENDS">
<id name="id" type="long">
<generator class="native" />
</id>
<!-- *** -->
<set name="relatedFriends" table="RELATED_FRIENDS">
<key column="FRIEND_ID" />
<many-to-many column="RELATED_FRIEND_ID" class="Friend" entity-name="RelatedFriend"/>
</set>
</class>