Нужна помощь с запросом критериев гибернации по простой модели управления пользователями - PullRequest
0 голосов
/ 20 июля 2011

Я работаю над управлением пользователями, которое позволяет пользователям иметь разрешение, независимо от того, к каким ролям они принадлежат.

Итак, вот основная идея: существует двунаправленный метод «многие ко многим», использующий 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=?

Так есть что-то, что я оставляю, не видя, не рассматривая? Что-нибудь в стороне, что метод работает нормально. Может ли кто-нибудь пролить свет?

спасибо за чтение

Ответы [ 2 ]

1 голос
/ 31 июля 2011

Если вы хотите вернуть пользователя, даже если у него нет особых прав, вы не можете запросить его, как будто там ничего нет, вы ничего не получите назад. Добавление 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
   }
}
0 голосов
/ 24 февраля 2012

, чтобы получить записи, даже если у вас нет особых прав, вам нужно присоединиться слева

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();
...