简体   繁体   English

Hibernate删除关系manyToMany

[英]Hibernate remove relation manyToMany

I have 3 tables Role, User, and UserRole. 我有3个表Role,User和UserRole。 The table UserRole contains the mapping between user and role along with the two corresponding index columns. 表UserRole包含用户和角色之间的映射以及两个相应的索引列。 I am using hibernate with annotations, and would like to be able to "Revoke" a role from the user, but this is turning out to be somewhat difficult. 我正在使用带有注释的休眠模式,并且希望能够从用户“撤消”角色,但是事实证明这有点困难。

In my User Class I have 在我的用户类别中,

@ManyToMany(fetch=FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST}, targetEntity = Role.class)
    @IndexColumn(name = "role_index", base = 0)
    @NotFound(action=NotFoundAction.IGNORE)
    @JoinTable(name = "tblUser_Role", joinColumns={
    @JoinColumn(name = "UID")}, inverseJoinColumns={
    @JoinColumn(name = "roleid", nullable = false)})
    private List<Role> roles = new ArrayList<Role>(0);

In my Role class I have 在我的角色课上,我有

@ManyToMany(fetch=FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST}, mappedBy="roles")
    private List<User> users = new ArrayList<User>(0);

and the DAO method I am calling to "Revoke" the role(s) is 我调用的DAO方法“撤消”角色是

@Override
    public boolean revokeRolesFromUserAccount(User user, List<Role> userRoles) {
        if (log.isInfoEnabled()) {
            log.info("Roles revoked from the User " + user.getUsername());
        }
        if (user == null) {
            return false;
        }
        if (userRoles == null) {
            return false;
        }

        Iterator<Role> iter = userRoles.iterator();
        List<Role> newroles = new ArrayList<Role>(0);
        Role role = null;
        while (iter.hasNext()) {
            role = (Role) this.sessionFactory.getCurrentSession().load(
                    Role.class, iter.next().getRoleid());
            newroles.add(role);
        }

        User newUser = null;
        newUser = (User) this.sessionFactory.getCurrentSession().load(User.class, user.getUid());
        newUser.getRoles().removeAll(newroles);
        this.sessionFactory.getCurrentSession().saveOrUpdate(newUser);
        return true;

    }

for some reason this does not work as expected, when breaking through I noticed the roles were not being initialized I guess due to the LazyLoading, and I tried doing something like Hibernate.initialize(newUser.getRoles()) but this did not change anything. 由于某种原因,这不能按预期工作,突破时我注意到角色未初始化,我猜是由于Hibernate.initialize(newUser.getRoles())造成的,我尝试做类似Hibernate.initialize(newUser.getRoles())但这并没有改变任何内容。 I am still learning the ropes with hibernate and am not sure what I am missing, maybe something very obvious?? 我仍在用冬眠学习绳索,不确定自己缺少什么,也许很明显吗? Thank you so much for your time and thoughts in advance! 非常感谢您的时间和事先的想法!

UPDATE: After trying the fixes suggested by Paujo and Matin Kh and doing further debugging I still have not seen any differences in the Roles being loaded in after line newUser = (User) this.sessionFactory.getCurrentSession().load(User.class, user.getUid()); 更新:尝试了Paujo和Matin Kh建议的修复程序并进行了进一步的调试后,我仍然没有看到在newUser = (User) this.sessionFactory.getCurrentSession().load(User.class, user.getUid());

Here is a copy of my tblUser_Role, not sure if this helps. 这是我的tblUser_Role的副本,不确定是否有帮助。 Thanks again! 再次感谢!

(Adding roles works just fine) (添加角色就可以了)

在此处输入图片说明

I'm having the exact situation here. 我在这里有确切的情况。 Your question has a very simple solution. 您的问题有一个非常简单的解决方案。

For one of your classes use EAGER , and for the other one use LAZY . 对于您的一个类,请使用EAGER ;对于另一类,请使用LAZY Try this: 尝试这个:

Role: 角色:

@ManyToMany(fetch=FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST}, mappedBy="roles")
private List<User> users = new ArrayList<User>(0);

User: 用户:

@ManyToMany(fetch=FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST}, targetEntity = Role.class)
@IndexColumn(name = "role_index", base = 0)
@NotFound(action=NotFoundAction.IGNORE)
@JoinTable(name = "tblUser_Role", joinColumns={
@JoinColumn(name = "UID")}, inverseJoinColumns={
@JoinColumn(name = "roleid", nullable = false)})
private List<Role> roles = new ArrayList<Role>(0);

I think your approach should be different. 我认为您的方法应该有所不同。

UserRole should have a role name. UserRole应该具有角色名称。

Your User should have a list of UserRole items or just one UserRole but with a hierarchy of UserRole. 您的用户应具有一个UserRole项列表,或者只有一个UserRole,但具有UserRole层次结构。 But as you have a list that is ok. 但是,因为您有一个可以的列表。

So basically you have references in User to UserRole so there is no need to have references to User in UserRole. 因此,基本上,您在UserRole中有对User的引用,因此在UserRole中没有对User的引用。

That way your table becomes very simple and you dont need any joins to do it and you can then just select UserRole by name. 这样,您的表就变得非常简单,并且不需要任何连接即可,然后可以按名称选择UserRole。

After that you should be able to remove the reference from the list of UserRole in User and merge the User. 之后,您应该能够从User中的UserRole列表中删除引用并合并User。

Finally got this working, mostly by sheer luck, this is what I ended up with in my RoleDaoImpl class. 最终,主要是靠运气,这项工作终于完成了,这就是我在RoleDaoImpl类中得到的结果。

@Override
    @Transactional
    public boolean revokeRolesFromUserAccount(User user, List<Role> userRoles) {        
        if (user == null) {
            return false;
        }
        if (userRoles == null) {
            return false;
        }   

        User newUser = null;
        newUser = (User) this.sessionFactory.getCurrentSession().load(User.class, user.getUid());   

        List<Role> newRoleList = newUser.getRoles();

        newRoleList.removeAll(userRoles);

        if(newUser.getRoles().retainAll(newRoleList)){
            if (log.isInfoEnabled()) {
                log.info("Roles revoked from the User " + user.getUsername());
            }
            this.sessionFactory.getCurrentSession().saveOrUpdate(newUser);          
            return true;
        }else{
            return false;
    }

Hope this can be of some use to others in the future! 希望将来对其他人有用!

Thanks again for everyone's help! 再次感谢大家的帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM