2012-08-31 261 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

我想再試一次我會告訴你有關結果 –