0

我一直致力于用户管理,允许用户除了他们所属的角色之外还有权限。

所以这是一般的想法:在 User-Role、Role-Right 之间使用可连接的多对多双向,并且在 User-UserSpecialRight 之间使用类的多对多(双一对多)双向并且 Right-UserSpecialRight 多对一的一侧在 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为您创建这种情况。

相反,从查询中删除特殊权限部分,并在返回用户对象后初始化关联。

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 回答