我一直致力于用户管理,允许用户除了他们所属的角色之外还有权限。
所以这是一般的想法:在 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=?
那么有什么我没有看到,没有考虑的东西吗?除了这种方法之外的任何东西都可以正常工作。有人能解释一下吗?
谢谢阅读