[英]Updating ManyToMany relationships in JPA or Hibernate
我有两个像下面这样的Entity
......
@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
...
方法#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
第二个方法工作正常,而不是第一个。
该问题是一个Owning Entity
问题。
假设Staff
是User
的子类,您的问题是关系的只有一侧是拥有实体。 mappedBy = "groupMemberList"
使Group
实体成为拥有实体,因此只保留对该实体的更改。 这意味着您必须在两种情况下更新Group
实体中的groupMemberList
。 如果您有一个User
组列表,那么您必须遍历组列表并将User
添加到其中。 User
的groupList
仅用于检索。
给定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 (?, ?)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.