Pregunta
Tengo una bastante simple SQL I necesidad de realizar.
Tengo un ProcessUser
, Role
y una mesa ProcessUserRole
. Un sencillo de muchos a muchos
Quiero seleccionar todos de ProcessUser
que no tienen también un papel de administrador.
Sin embargo, mi JPQL falla porque mi usuario también tiene función oficial, por lo que se recupera en la lista.
Esta es la JPQL:
entityManager.createQuery("SELECT p FROM " + ProcessUser.class.getName()
+ " p join p.roles role WHERE role.name NOT IN ('sysadmin')").getResultList();
El SQL generado es:
select distinct processuse0_.id as id8_, processuse0_.position as position8_, processuse0_.username as username8_, processuse0_.organization_id as organiza9_8_, processuse0_.passwordHash as password4_8_, processuse0_.fromEmail as fromEmail8_, processuse0_.firstname as firstname8_, processuse0_.lastname as lastname8_, processuse0_.processes as processes8_ from ProcessUser processuse0_ inner join ProcessUserRoles roles1_ on processuse0_.id=roles1_.userId inner join Role role2_ on roles1_.roleId=role2_.id where ( role2_.name not in ( 'sysadmin' ) )
Solución
sintaxis adecuada JPQL usando subconsulta:
SELECT p FROM ProcessUser p
WHERE p.id NOT IN (
SELECT p2.id FROM ProcessUser p2
JOIN p2.roles role
WHERE role.name='sysadmin'
)
Otros consejos
¿Funcionará para usted?
SELECT *
FROM ProcessUser
WHERE Exists
(
SELECT 1
FROM
ProcessUserRoles
INNER JOIN Roles
ON Roles.RoleId = ProcessUserRoles.RoleId
WHERE 1=1
AND ProcessUser.ProcessUserId = ProcessUserRoles.ProcessUserId
AND Roles.RoleDescription = 'Super User'
)
Su consulta es, básicamente, trayendo de vuelta una lista de usuarios / roles ya que su usuario tiene dos papeles que regresa dos veces, filtrar una fila al excluir el papel de 'administrador de sistemas'. Lo que parece que usted quiere hacer es excluir a todos los usuarios que tienen un papel de 'administrador de sistemas', independientemente de que tengan otras funciones. Usted tendría que añadir algo a su búsqueda gusta. (Voy solicitada no su descripción)
where processuse0_.id not in
select ( userId from
ProcessUserRoles
inner join
Role
on ProcessUserRoles.roleId=Role.id
where role.name != 'sysadmin'
)
Ejecutar una consulta anidada. Primero seleccione todos los usuarios con el rol de administrador de sistemas. A continuación, seleccione el complemento de esto, o todos los usuarios que no están en este resultado.
JPQL:
TypedQuery<ProcessUser> query = em.createQuery("" +
" SELECT p FROM ProcessUser p " +
" WHERE p.roles.name <> ?1", ProcessUser.class);
query.setParameter(1, "sysadmin");
return query.getResultList;