0

我有 3 个表角色、用户和用户角色。表 UserRole 包含用户和角色之间的映射以及两个对应的索引列。我正在使用带有注释的休眠,并且希望能够“撤销”用户的角色,但这变得有些困难。

在我的用户类中,我有

@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);

在我的角色课上,我有

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

和我调用“撤销”角色的 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;

    }

出于某种原因,这不能按预期工作,当突破时我注意到角色没有被初始化我猜是由于 LazyLoading,我尝试做类似的事情,Hibernate.initialize(newUser.getRoles())但这并没有改变任何东西。我仍在学习休眠的绳索,不确定我错过了什么,也许是非常明显的东西?非常感谢您提前抽出时间和想法!

更新:在尝试了 Paujo 和 Matin Kh 建议的修复程序并进行进一步调试后,我仍然没有看到在后行加载的角色有任何差异newUser = (User) this.sessionFactory.getCurrentSession().load(User.class, user.getUid());

这是我的 tblUser_Role 的副本,不确定这是否有帮助。再次感谢!

(添加角色就可以了)

在此处输入图像描述

4

3 回答 3

1

我这里有确切的情况。您的问题有一个非常简单的解决方案。

对于您的一个类使用EAGER,而对于另一个类使用LAZY。试试这个:

角色:

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

用户:

@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);
于 2012-09-01T04:59:46.183 回答
0

我认为你的方法应该不同。

UserRole 应该有一个角色名称。

您的用户应该有一个 UserRole 项目列表或只有一个 UserRole 但具有 UserRole 层次结构。但是因为你有一个可以的列表。

所以基本上你在 User 中有对 UserRole 的引用,所以不需要在 UserRole 中有对 User 的引用。

这样,您的表格就变得非常简单,您不需要任何连接即可,然后您只需按名称选择 UserRole。

之后,您应该能够从 User 中的 UserRole 列表中删除引用并合并用户。

于 2012-08-31T22:35:00.130 回答
0

最终得到了这个工作,主要是靠运气,这就是我在 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;
    }

希望这对将来的其他人有用!

再次感谢大家的帮助!

于 2012-09-04T19:46:15.623 回答