Я работаю над управлением пользователями, которое позволяет пользователям иметь разрешение, независимо от того, к каким ролям они принадлежат.
Итак, вот основная идея: существует двунаправленный метод «многие ко многим», использующий jointable между User-Role, Role-Right, и существует двунаправленный метод «многие ко многим» (double one-to-many), использующий класс между 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;
}
}
так что метод с комментирующей частью успешен в моем тестовом классе, но затем специальная правая часть полностью игнорируется. Но как только комментарии удалены, он возвращает ноль, следовательно, тест не пройден.
в настоящий момент нет никаких особых прав для пользователей по умолчанию в моих приборах (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=?
Так есть что-то, что я оставляю, не видя, не рассматривая? Что-нибудь в стороне, что метод работает нормально. Может ли кто-нибудь пролить свет?
спасибо за чтение