问题描述
我有两个Entity
,如下所示...
I have two Entity
like below...
@Entity
@Table(name = "USER")
public class User {
@Id
private Long id;
private String name;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "groupMemberList")
@Fetch(FetchMode.SELECT)
private List<Group> groupList = new ArrayList<>();
// Getters - Setters
}
@Entity
@Table(name = "GROUP")
public class Group {
@Id
private Long id;
private String name;
@ManyToMany(fetch = FetchType.LAZY/*, mappedBy = "groupList"*/)
@Fetch(FetchMode.SELECT)
@JoinTable(name = "SEC_GROUP_VS_MEMBER", joinColumns = @JoinColumn(name = "GROUP_ID"),
inverseJoinColumns = @JoinColumn(name = "MEMBER_ID"))
private List<User> groupMemberList;
// Getters - Setters
}
我想有时使用以下方法来更新User
,有时也要更新Group
...
I want to update the User
sometimes and also Group
sometimes with the methods below...
方法#1
public boolean updateGroup(Long groupId, List<Staff> groupMemberList) {
Group group = hibernateTemplate.get(Group.class, groupId);
group.setGroupMemberList(groupMemberList);
hibernateTemplate.merge(group); // Group updated with the users
return true;
}
方法#2
public boolean updateUser(Long userId, List<Group> groupList) {
User user = hibernateTemplate.get(User.class, userId);
user.setGroupList(groupList);
hibernateTemplate.merge(user); // User not updated with the groups
return true;
}
第一种方法可以正常工作,但第二种则不能.但是,当我将join table
从Group.class
移到User.class
时,第二种方法可以正常工作,而不是第一种.
The first method works fine but not the second one. BUT when I move the join table
from Group.class
to User.class
then second method works fine and not the first one.
推荐答案
问题是Owning Entity
问题.
假定Staff
是User
的子类,则您的问题是,关系的仅一方是拥有实体. mappedBy = "groupMemberList"
使Group
实体成为拥有实体,因此仅保留对该实体的更改.这意味着在两种情况下,您都必须更新Group
实体中的groupMemberList
.如果您有User
的组列表,则必须遍历组列表并将User
添加到其中. User
中的groupList
仅用于检索.
Assuming that Staff
is a subclass of User
, your issue is that only one side of the relationship is the owning entity. The mappedBy = "groupMemberList"
makes the Group
entity the owning entity and so only changes to that entity are persisted. This means that you have to update the groupMemberList
in the Group
entity in both cases. If you have a list of groups for a User
then you have to iterate over the list of groups and add the User
to it. The groupList
in User
is only for retrieval.
给出User
和GroupMember
实体:
@Entity
public class User {
@Id @GeneratedValue
private Long id;
@ManyToMany(mappedBy = "groupMemberList")
private List<GroupMember> groupList;
@Entity
public class GroupMember {
@Id @GeneratedValue
private Long id;
@ManyToMany
private List<User> groupMemberList;
然后:
// create starting user and membergroup
tx.begin();
User user = new User();
em.persist(user);
GroupMember group = new GroupMember();
em.persist(group);
tx.commit();
em.clear();
// update users for groupId 2
System.out.println("update users for groupId 2");
tx.begin();
List<User> users = new ArrayList<>();
users.add(user);
group.setGroupMemberList(users);
em.merge(group);
tx.commit();
em.clear();
// update groups for userId 1 -- doesn't work, not owner of relationship
System.out.println("update groups for userId 1 -- doesn't work, not owner of relationship");
tx.begin();
List<GroupMember> groups = new ArrayList<>();
groups.add(group);
user.setGroupList(groups);
em.merge(user);
tx.commit();
em.clear();
// update groups for userId 1 -- works
System.out.println("update groups for userId 1 -- works");
tx.begin();
for ( GroupMember groupMember: groups) {
groupMember.getGroupMemberList().add(user);
em.merge(groupMember);
}
tx.commit();
em.clear();
给出以下SQL输出:
Hibernate: insert into User (id) values (?)
Hibernate: insert into GroupMember (id) values (?)
update users for groupId 2
Hibernate: select groupmembe0_.id as id1_0_0_ from GroupMember groupmembe0_ where groupmembe0_.id=?
Hibernate: select groupmembe0_.groupList_id as groupLis1_1_0_, groupmembe0_.groupMemberList_id as groupMem2_1_0_, user1_.id as id1_4_1_ from GroupMember_User groupmembe0_ inner join User user1_ on groupmembe0_.groupMemberList_id=user1_.id where groupmembe0_.groupList_id=?
Hibernate: select user0_.id as id1_4_0_ from User user0_ where user0_.id=?
Hibernate: insert into GroupMember_User (groupList_id, groupMemberList_id) values (?, ?)
update groups for userId 1 -- doesn't work, not owner of relationship
Hibernate: select user0_.id as id1_4_0_ from User user0_ where user0_.id=?
Hibernate: select groupmembe0_.id as id1_0_0_ from GroupMember groupmembe0_ where groupmembe0_.id=?
update groups for userId 1 -- works
Hibernate: select groupmembe0_.id as id1_0_0_ from GroupMember groupmembe0_ where groupmembe0_.id=?
Hibernate: select groupmembe0_.groupList_id as groupLis1_1_0_, groupmembe0_.groupMemberList_id as groupMem2_1_0_, user1_.id as id1_4_1_ from GroupMember_User groupmembe0_ inner join User user1_ on groupmembe0_.groupMemberList_id=user1_.id where groupmembe0_.groupList_id=?
Hibernate: delete from GroupMember_User where groupList_id=?
Hibernate: insert into GroupMember_User (groupList_id, groupMemberList_id) values (?, ?)
Hibernate: insert into GroupMember_User (groupList_id, groupMemberList_id) values (?, ?)
参考: MappedBy是双向的@ManyToMany:是什么原因
JPA - difference in the use of the mappedBy property to define the owning entity
这篇关于在JPA或Hibernate中更新ManyToMany关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!