需要有关简单用户管理模型的休眠条件查询的帮助
我一直在研究用户管理,它允许用户拥有除其所属角色之外的权限。
所以这里是总体思路:在 User-Role、Role-Right 之间使用可连接的多对多双向,并且在 User-UserSpecialRight 之间使用类的多对多(双一对多)双向而 Right-UserSpecialRight 多对一一侧位于 UserSpecialRight 一侧。
现在我正在使用 Hibernate3.6.1.FINAL+Spring3.0.5.RELEASE+Maven+shiro。使用标准我想提取用户所属角色的所有权限,包括特殊权限。 这是映射
@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;
}
好的,这就是关于映射的内容,我希望它不会太长。在 RightDAOImpl 中,我有以下方法,但无法给出我想要的结果。
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=?
那么有什么我没有看到、没有考虑的遗漏吗?除了该方法之外,任何方法都可以正常工作。任何人都可以透露一些信息吗?
感谢您的阅读
i've been working on a user management which allow users to have permission aside what the roles they belongs to.
so here is the general idea: there is many-to-many bidirectional using jointable between User-Role, Role-Right and there is a many-to-many(double one-to-many) birectional using a class between User-UserSpecialRight and Right-UserSpecialRight the many-to-one side is on the UserSpecialRight side.
Now i'm using Hibernate3.6.1.FINAL+Spring3.0.5.RELEASE+Maven+shiro.using criteria i would like to pull all the rights of a user those for the roles he belogngs to including special rights.
here is the mapping
@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;
}
ok that's about the mapping i hope it's not too long. in the RighDAOImpl i have this following method which could not give me the result i wanted.
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;
}
}
so the method with the commenting part is successful in my test class but then the special right part is completely ignored.but once the comments are removed it returns null hence the test fails.
at the present moment there is no specialrights for any of the defaults users in my fixtures (import.sql) but i believe the query should still return the rights even if there is no special rights.
here is the query when i turn the criteria method without the comments :
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=?
So is there anything that i'm leaving out not seeing , not considering? anything aside that method works fine.Can anyone shed some lights?
thanks for reading
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果你想返回一个用户,即使他们没有特殊权利,那么你就不能查询它,就好像那里什么也没有一样,你不会得到任何东西。添加
Restrictions.eq
会为您带来这种情况。相反,请从查询中删除特殊权限部分,并在返回用户对象后初始化关联。
If you want to return a User even if they don't have Special Rights, then you can't query on it, as if there is nothing there, you won't get anything back. Adding the
Restrictions.eq
creates this situation for you.Instead, remove the Special Rights section from your query and initialize the association once the User object is returned.
即使没有特殊权限也要获取记录,您需要左连接
to get the records even when there are no special rights you need a left join