代码之家  ›  专栏  ›  技术社区  ›  Mr. Mak

在JPA或Hibernate中更新许多关系

  •  1
  • Mr. Mak  · 技术社区  · 6 年前

    我有两个 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;
    }
    

    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 第二种方法很好,而不是第一种。

    1 回复  |  直到 6 年前
        1
  •  5
  •   K.Nicholas    6 年前

    这个问题是个问题 Owning Entity 问题。

    Staff 是的一个子类 User ,您的问题是关系中只有一方是所属实体。这个 mappedBy = "groupMemberList" 使 Group 实体拥有的实体,因此只保留对该实体的更改。这意味着您必须更新 groupMemberList 两种情况下的实体。如果您有一个 用户 然后您必须遍历组列表并添加 去吧。这个 groupList 用户 仅用于检索。

    鉴于 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 in bi-directional @ManyToMany : what is the reason

    JPA - difference in the use of the mappedBy property to define the owning entity