Pergunta

Eu tenho um SQL bastante simples que preciso executar.

eu tenho um ProcessUser, Role e a ProcessUserRole tabela. Um direto para muitos para muitos

Eu quero selecionar tudo ProcessUserIsso também tem um papel de administrador.

No entanto, meu JPQL falha porque meu usuário também possui oficial de função, por isso é recuperado na lista.

Aqui está o JPQL:

entityManager.createQuery("SELECT p FROM " + ProcessUser.class.getName() 
  + " p join p.roles role WHERE role.name NOT IN ('sysadmin')").getResultList();

O SQL gerado é:

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'
            )
        )
Foi útil?

Solução

Sintaxe JPQL adequada usando a 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'
 )

Outras dicas

Isso funcionará para você?

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

Sua consulta está basicamente trazendo de volta uma lista de usuários/funções, pois seu usuário tem duas funções que ele volta duas vezes, você filtra uma linha, excluindo o papel de 'sysadmin'. O que você deseja fazer é excluir todos os usuários que têm um papel de 'sysadmin', independentemente de terem outros papéis. Você precisaria adicionar algo a você, como. (Estou passando por sua consulta, não sua descrição)

  where processuse0_.id not in 
  select ( userId  from 
           ProcessUserRoles
           inner join 
           Role 
           on ProcessUserRoles.roleId=Role.id 
           where role.name != 'sysadmin'

           )

Execute uma consulta aninhada. Primeiro, selecione todos os usuários com a função de sysadmin. Em seguida, selecione o complemento disso ou de todos os usuários que não estão nesse 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;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top