0

Role、User、および UserRole の 3 つのテーブルがあります。テーブル UserRole には、ユーザーとロールの間のマッピングと、対応する 2 つのインデックス列が含まれています。私は注釈付きの休止状態を使用しており、ユーザーからロールを「取り消す」ことができるようにしたいと考えていますが、これはやや難しいことが判明しています。

私のユーザークラスには

@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クラスの 1 つには を使用し、もう 1 つのクラスには を使用します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

ついにこれが機能するようになりました。ほとんどの場合、これが私の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 に答える
0

あなたのアプローチは違うべきだと思います。

UserRole にはロール名が必要です。

ユーザーには、UserRole アイテムのリスト、または UserRole を 1 つだけ持つ必要がありますが、UserRole の階層があります。しかし、あなたは大丈夫なリストを持っているので。

したがって、基本的に User に UserRole への参照があるため、UserRole に User への参照を含める必要はありません。

そうすれば、テーブルが非常にシンプルになり、結合を行う必要がなくなり、名前で UserRole を選択するだけで済みます。

その後、User の UserRole のリストから参照を削除し、User をマージできるはずです。

于 2012-08-31T22:35:00.130 に答える