【问题标题】:How make both sides of many-to-many relation ships owner?如何使多对多关系的双方都拥有?
【发布时间】:2014-01-26 08:07:24
【问题描述】:
我有一个班级Group 和一个班级User
其中 Group 和 User 是多对多关系
如果我更改user 的groups 并保存user 我想更新groups
反之亦然,如果我更改了group 的user 并保存group,我希望更新user
我必须在两个类中设置mappedBy
注意:我使用的是eclipseLink
【问题讨论】:
标签:
java
jpa
many-to-many
eclipselink
【解决方案1】:
对于多对多关系,您需要更新双方的关系数据以保持一致。
可惜没有捷径。
您可以做的是在实体或第三个类上创建一个方法来封装一致的更新。
当心无限循环 - 不要在两个实体类中实现对另一个实体的传播。
大概是这样的:
public class User
...
public void addGroup(Group g){
groups.add(g);
g.addUser(this);
}
或
public class Group
...
public void addUser(User u){
users.add(u);
u.addGroup(this);
}
我假设关系注释上存在适当的级联设置。
【解决方案2】:
拥有关系和双向引用是有区别的。前者主要涉及数据库的布局,而后者涉及您的应用程序逻辑。根据您的问题,我假设您想要后者。同时,通常建议关系的只有一侧拥有引用。您可以通过创建强制双向引用的添加和删除方法轻松创建双向引用,同时保持明确的集合所有者:
class Group {
@ManyToMany
private Collection<User> users = ... ;
public void addUser(User user) {
if(user != null && !users.contains(user)) {
users.add(user)
user.addGroup(this);
}
}
public void removeUser(User user) {
if(user != null && users.contains(user)) {
users.remove(user)
user.removeGroup(this);
}
}
}
class User {
@ManyToMany(mappedBy="users")
private Collection<Group> groups = ... ;
public void addGroup(Group group) {
if(group != null && !groups.contains(group)) {
groups.add(group)
group.addUser(this);
}
}
public void removeGroup(Group group) {
if(group != null && groups.contains(group)) {
groups.remove(group)
group.removeUser(this);
}
}
}
在此示例中,Group 拥有不影响应用程序逻辑的关系。请注意操作顺序以避免无限循环。另请注意,此代码不是线程安全的。
【解决方案3】:
我知道对于作者来说有点晚了,但也许它会对其他读者有所帮助。
您可以通过为双方添加@JoinTable 来实现:
(级联您可以根据需要添加)
public class Group {
....
@ManyToMany
@JoinTable(
name = "group_user",
joinColumns = @JoinColumn(name = "groups_id"),
inverseJoinColumns = @JoinColumn(name = "users_id"))
private List<User> users;
}
public class User {
....
@ManyToMany
@JoinTable(
name = "group_user",
joinColumns = @JoinColumn(name = "users_id"),
inverseJoinColumns = @JoinColumn(name = "groups_id"))
private List<Group> groups;
}