【问题标题】:How make both sides of many-to-many relation ships owner?如何使多对多关系的双方都拥有?
【发布时间】:2014-01-26 08:07:24
【问题描述】:

我有一个班级Group 和一个班级User
其中 Group 和 User 是多对多关系
如果我更改usergroups 并保存user 我想更新groups
反之亦然,如果我更改了groupuser 并保存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;
        }
        

        【讨论】:

          猜你喜欢
          • 2013-09-15
          • 1970-01-01
          • 2011-07-12
          • 2014-03-25
          • 1970-01-01
          • 2017-08-25
          • 2016-09-07
          • 2015-02-24
          • 1970-01-01
          相关资源
          最近更新 更多