2012-08-31 213 views
0

我有3个表角色,用户和UserRole。 UserRole表包含用户和角色之间的映射以及两个相应的索引列。我在注释中使用hibernate,希望能够从用户那里“撤销”一个角色,但是这会变得有点困难。休眠删除关系manyToMany

在我的用户类我有

@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方法我打电话到 “撤销” 的角色(s)为

@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())但这并没有改变任何东西。我仍然在学习与hibernate的绳索,我不知道我错过了什么,也许是非常明显的?提前感谢您的时间和想法!

UPDATE:试图通过Paujo和晨报的Kh建议的修复和做进一步的调试我还没有看到在角色的任何差异被加载后线newUser = (User) this.sessionFactory.getCurrentSession().load(User.class, user.getUid());

这里后我tblUser_Role的副本,不知道如果这有帮助。再次感谢!

(添加角色只是罚款)

enter image description here

+0

将'@ Transactional'添加到'revokeRolesFromUserAccount'应该处理LazyLoading的问题。你在调用'revokeRolesFromUserAccount'时会得到异常吗?当你调试这行'newUser.getRoles()。removeAll(newroles);'时,用户中是否有任何角色? – Pao

+0

谢谢你的回应!这似乎并没有解决EAGER加载问题。调试时,似乎角色仍然没有加载到newUser中,只是在'newUser =(User)this.sessionFactory.getCurrentSession()。load(User.class,user.getUid());'行后面。 (我也做了Matin Kh建议的修改,并在'Role'中的'List '上添加了'fetch = FetchType.EAGER'任何其他想法都将不胜感激!再次感谢! – Curt

回答

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; 
    } 

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

再次感谢大家的帮助!

0

我觉得你的做法应该是不同的。

UserRole应该有一个角色名称。

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

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

这样你的表变得非常简单,你不需要任何连接来完成它,然后你可以通过名称选择UserRole。

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

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); 
+0

感谢您的回应!似乎修复了EAGER的加载问题,调试时似乎角色仍然没有加载到newUser中,只是在'newUser =(User)this.sessionFactory.getCurrentSession()。load(User.class,user.getUid()); '。任何额外的想法将不胜感激!再次感谢! – Curt

+0

我曾尝试在用户和角色上设置'fetch = FetchType.EAGER',并且这似乎也没有区别。 – Curt

+0

我想再试一次我会告诉你有关结果 –