2009-10-16 8 views
11

Tengo un SQL bastante simple que necesito realizar.JPQL, Cómo NO seleccionar algo

Tengo un ProcessUser, Role y un ProcessUserRole mesa. Un straight forward many-to-many

Quiero seleccionar todos los ProcessUser que también tienen un rol de administrador.

Sin embargo, mi JPQL falla porque mi usuario también tiene un agente de función, por lo que se recupera en la lista.

Aquí es el 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' 
      ) 
     ) 
+0

usted dice que quiere incluir un papel de ADMIN , pero su muestra muestra ROLE NAME NOT IN SysAdmin. ¿Puedes explicar? –

+0

@Shervin - debe tener cuidado con sus etiquetas; la mayoría de las respuestas a continuación son incorrectas porque ha etiquetado su pregunta como "SQL" (ahora cambiado a JPQL) – ChssPly76

+0

No, no quiero incluir admin (sysadmin). ProcessUser es un usuario y un administrador del sistema, por lo tanto, mi selección no me da lo que quiero. Quiero que el usuario sea omitido si tiene el rol sysadmin. –

Respuesta

17

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' 
) 
+0

Gracias, esto casi funcionó, sin embargo es correcto DONDE role.name == 'sysadmin' porque ya estás diciendo NO EN –

+0

Quise decir tan decir role.name = 'sysadmin' –

1

¿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' 
) 
+0

Esto es SQL directo, no JPQL. – ChssPly76

0

Ejecute una consulta anidada. Primero seleccione todos los usuarios con el rol de sysadmin. Luego seleccione el complemento de esto, o todos los usuarios que no están en este resultado.

1

Su consulta básicamente trae de vuelta una lista de usuarios/roles, ya que su usuario tiene dos roles: regresa dos veces, filtra una fila al excluir el rol de 'sysadmin'. Lo que parece que quiere hacer es excluir a todos los usuarios que tienen un rol de 'sysadmin' independientemente de si tienen otros roles. Necesitarías agregar algo a tu consulta como. (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' 

      ) 
+1

Nuevamente, esto es SQL, no JPQL. – ChssPly76

+0

@ ChssPly76 Bueno, la esperanza es publicar el sql lo orientará en la dirección correcta para arreglar su JPQL especialmente dado que nadie estaba ofreciendo una solución JPQL. De hecho, no publicaste uno hasta 50 minutos después de haber señalado que las respuestas de otras personas no eran JPQL – Gratzy

+0

Probablemente, esa "esperanza" debiera haberse mencionado en tu respuesta. Tenga en cuenta que no lo rechacé; Solo estoy señalando que esta no es realmente una solución válida para la pregunta de OP. En cuanto a "50 minutos después", espere para ver si usted o alguien más en este hilo actualizaría sus respuestas para luego contener JPSQL después de mis comentarios, así puedo votarlos y solo he publicado mi respuesta después de eso no sucedió – ChssPly76

0

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; 
Cuestiones relacionadas