2012-07-03 58 views
5

Tengo una tabla de Usuarios, tabla de proyectos y la de User_Roles. Tengo un usuario que está conectado a 2 proyectos, pero cuando tengo solo un rol para él, devuelve esos 2 proyectos, pero si tengo 2 roles para él, devuelve 4 roles (proyectos 2x2). ¿Cómo evito que esteHibernate devuelve el duplicado porque otra tabla tiene valores duplicados

Este es mi código para devolver la lista de proyectos para el usuario

@Override 
public List<Project> retrieve(User user) { 
    Criteria criteria = super.createCriteria(); 
    criteria.addOrder(Order.desc("date")); 
    criteria.createCriteria("users").add(Restrictions.eq("id", user.getId())); 

    return (List<Project>) criteria.list(); 
} 

asignaciones de clase Usuario

@ManyToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "Users_Projects", 
      joinColumns = @JoinColumn(name = "UserID"), inverseJoinColumns = @JoinColumn(name = "ProjectID")) 
public List<Project> getProjects() { 
    return projects; 
} 

@ElementCollection(fetch = FetchType.EAGER) 
@Enumerated(EnumType.STRING) 
@Column(name = "RoleType") 
@JoinTable(name = "User_Roles", joinColumns = @JoinColumn(name = "UserID")) 
public Set<Role> getRoles() { 
    return roles; 
} 

Cualquier sugerencia cuál es el problema aquí?

TNX

Respuesta

13

La "solución" clásica para cuestiones de filas duplicadas de consultas de criterios, lo que probablemente va a funcionar todo el tiempo que no está tratando de combinarlo con paginación, es agregar

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 

Creo que esto está sucediendo en su situación debido a la carga ansiosa de los roles de usuario. Cambiar eso para ser perezoso también podría funcionar, y seguir trabajando si necesita paginación.

Configuración fetch = FetchType.EAGER indica hibernate que siempre desea cargar todas las funciones para el usuario cada vez que recupera un usuario, lo que logra haciendo siempre una unión a la tabla de roles.

Lamentablemente, ese sql lleva a múltiples registros con el mismo usuario (uno para cada función), y luego tiene que enderezarse en Java después de ejecutar sql, que es lo que hace el transformador de resultados.

Mucho más por desgracia, si desea utilizar la paginación de la manera más natural con criterios de hibernación simples, usando criteria.setFirstResult y criteria.setMaxResults, las cosas suceden en el orden equivocado, por lo que estas consultas que necesitan el transformador resultado para evitar duplicados apenas no' t página derecha.

Para comprender un poco mejor toda la generación hibernate sql, aconsejo activar el registro del sql generado como se describe en this answer a otra pregunta Hibernate SO.

+1

gracias! funcionó como un amuleto, ¿puedes explicar por qué la carga de los roles te llevaría a esto? También estoy seguro de que este es el caso, pero simplemente no entiendo por qué el hecho de establecer algo que no forma parte de la conexión de los usuarios-proyectos causa esto. ¿Alguna idea? –

+0

Consulte mi actualización para saber más sobre la pregunta en su comentario. –

Cuestiones relacionadas