0

私は、ユーザーが所属するロール以外の権限をユーザーに付与できるようにするユーザー管理に取り組んでいます。

一般的な考え方は次のとおりです。User-Role、Role-Rightの間で結合可能な多対多の双方向があり、User-UserSpecialRight間のクラスを使用した多対多(ダブル1対多)の双方向がありますおよび Right-UserSpecialRight 多対 1 側は UserSpecialRight 側にあります。

今、私は Hibernate3.6.1.FINAL+Spring3.0.5.RELEASE+Maven+shiro.using 基準を使用しています。ユーザーのすべての権利を、彼が特別な権利を含むロールに割り当てたいと考えています。ここにマッピングがあります

@Entity
@Table(name = "user", uniqueConstraints = {
@UniqueConstraint(columnNames = {"email"})})
@Component("user")
public class User {

//......
public User() {
    //......
}


@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid.hex")
@Column(name = "user_id", length = 36)
private String id;
@Column(name = "email", length = 150)
private String email;
@Column(name = "password", length = 150)
private String password;
// ...

@ManyToMany(fetch=FetchType.LAZY, mappedBy="users")
private Set<Role> roles = new HashSet<Role>();

@OneToMany(targetEntity=UserRightAssoc.class,fetch=FetchType.LAZY,mappedBy="user")
private Set<UserRightAssoc> specialrights = new HashSet<UserRightAssoc>();

//.....
}


 @Entity
 @Table(name = "role")
 @Component("role")
 public class Role {

//....
public Role() {
    //....
}
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "role_id", length = 36)
private String id;

@Column(name = "role_name")
private String roleName;

//....

@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "role_user_map", joinColumns = {
@JoinColumn(name = "role_id")},
inverseJoinColumns = {
@JoinColumn(name = "user_id")})
private Set<User> users = new HashSet<User>();

@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "role_right_map", joinColumns = {
@JoinColumn(name = "role_id")},
inverseJoinColumns = {
@JoinColumn(name = "right_id")})
private Set<Right> rights = new HashSet<Right>();
//.....
}  


 @Entity
 @Table(name = "rights")
 @Component("right")
 public class Right {

@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name="right_id")
private String id;
@Column(name = "right_name",unique=true)
private String rightName;
@Column(name = "description")
private String description;

@ManyToMany(fetch = FetchType.LAZY, mappedBy = "rights")
private Set<Role> roles = new HashSet<Role>();

@OneToMany(targetEntity=UserRightAssoc.class,fetch=FetchType.LAZY,mappedBy="right")
private Set<UserRightAssoc> specialrights = new HashSet<UserRightAssoc>();
//...... 
}


@Entity
@Table(name = "user_right_assoc")
@Component("userrightassoc")
public class UserRightAssoc {

//....

@Embeddable
public static class Id implements Serializable {

    @Column(name="user_id")
    private String userId;

    @Column(name="rightId")
    private String rightId;

    public Id(){}

    public Id(String userId, String rightId) {
        this.userId = userId;
        this.rightId = rightId;
    }

    // equal and hashcode
}

@EmbeddedId
private Id id = new Id();

@Temporal(TemporalType.TIMESTAMP)
private Date dateCreate = new Date();

@ManyToOne(fetch=FetchType.LAZY,targetEntity=User.class)
@JoinColumn(name="user_id", insertable=false, updatable=false)
private User user;

@ManyToOne
@JoinColumn(name="right_id", insertable=false, updatable=false)
private Right right;

}

わかりました、それはマッピングについてです。長すぎないことを願っています。RighDAOImpl には、次のメソッドがあり、必要な結果が得られませんでした。

public Set<Right> getRightsByRoleAndEmail(String roleName, String email) {
    try {
        List list = this.getSessionFactory().getCurrentSession().createCriteria(this.getPersistentClass())
                .createAlias("roles", "r")
//              .createAlias("specialrights", "sp")
//              .createAlias("sp.user", "u")
                .add(Restrictions.eq("r.roleName", roleName))
//              .add(Restrictions.eq("u.email", email))
                .list();

        Set<Right> rigths = new HashSet<Right>(list);
        return rigths;
    } catch (Exception e) {
        logger.info("Error fecthing righs for a role and user", e);
        return null;
    }

}

したがって、コメント部分を含むメソッドはテスト クラスで成功しますが、特別な右側の部分は完全に無視されます。ただし、コメントが削除されると null が返されるため、テストは失敗します。

現時点では、フィクスチャ (import.sql) のデフォルト ユーザーには特別な権限はありませんが、特別な権限がなくても、クエリは権限を返す必要があると思います。

コメントなしで条件メソッドをオンにしたときのクエリは次のとおりです。

 select
    this_.right_id as right1_0_4_,
    this_.date_created as date2_0_4_,
    this_.description as descript3_0_4_,
    this_.last_modified as last4_0_4_,
    this_.right_name as right5_0_4_,
    roles5_.right_id as right2_0_,
    r1_.role_id as role1_,
    r1_.role_id as role1_1_0_,
    r1_.date_created as date2_1_0_,
    r1_.description as descript3_1_0_,
    r1_.last_modefied as last4_1_0_,
    r1_.role_name as role5_1_0_,
    sp2_.rightId as rightId3_1_,
    sp2_.user_id as user2_3_1_,
    sp2_.dateCreate as dateCreate3_1_,
    sp2_.right_id as right4_3_1_,
    right8_.right_id as right1_0_2_,
    right8_.date_created as date2_0_2_,
    right8_.description as descript3_0_2_,
    right8_.last_modified as last4_0_2_,
    right8_.right_name as right5_0_2_,
    u3_.user_id as user1_2_3_,
    u3_.dateCreated as dateCrea2_2_3_,
    u3_.email as email2_3_,
    u3_.full_name as full4_2_3_,
    u3_.lastLogin as lastLogin2_3_,
    u3_.lastModified as lastModi6_2_3_,
    u3_.password as password2_3_ 
from
    rights this_ 
inner join
    role_right_map roles5_ 
        on this_.right_id=roles5_.right_id 
inner join
    role r1_ 
        on roles5_.role_id=r1_.role_id 
inner join
    user_right_assoc sp2_ 
        on this_.right_id=sp2_.right_id 
left outer join
    rights right8_ 
        on sp2_.right_id=right8_.right_id 
inner join
    user u3_ 
        on sp2_.user_id=u3_.user_id 
where
    r1_.role_name=? 
    and u3_.email=?

それで、私が見ない、考えないで除外しているものはありますか?その方法は別として、うまくいきます。誰か光を当てることはできますか?

読んでくれてありがとう

4

2 に答える 2

1

ユーザーが特別な権利を持っていなくてもユーザーを返したい場合は、そこに何もないかのようにクエリを実行できません。何も返されません。を追加すると、Restrictions.eqこの状況が作成されます。

代わりに、クエリから Special Rights セクションを削除し、User オブジェクトが返されたら関連付けを初期化します。

List<User> list = this.getSessionFactory().getCurrentSession().createCriteria(User.class)
            .createAlias("roles", "r")
            .add(Restrictions.eq("r.roleName", roleName))
            .list();
for (User u : list) {
   if(u.getSpecialRights() != null) {
      u.getSpecialRights().size();  // loads the special rights if they are not null
   }
}
于 2011-07-31T18:03:01.593 に答える
0

特別な権利がない場合でもレコードを取得するには、左結合が必要です

List list = this.getSessionFactory().getCurrentSession().createCriteria(this.getPersistentClass())
    .createAlias("roles", "r")
    .createAlias("specialrights", "sp", JoinType.LeftOuterJoin)
    .createAlias("sp.user", "u", JoinType.LeftOuterJoin)
    .add(Restrictions.eq("r.roleName", roleName))
    .add(Restrictions.eq("u.email", email))
    .list();
于 2012-02-24T12:18:05.353 に答える