2009-10-16 4 views
11

Ho un SQL abbastanza semplice che devo eseguire.JPQL, Come NON selezionare qualcosa

Ho un ProcessUser, Role e una tabella ProcessUserRole. Un diretto molti-a-molti

Desidero selezionare tutti gli ProcessUser che ha anche un ruolo di amministratore.

Tuttavia il mio JPQL non funziona perché il mio utente ha anche un ruolo ufficiale, quindi viene recuperato nell'elenco.

Ecco la JPQL:

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

L'SQL generato è:

 
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

Tu dici che si desidera includere un ruolo di ADMIN , ma il tuo esempio mostra ROLE NAME NOT IN SysAdmin. Puoi spiegare? –

+0

@Shervin: devi stare attento con i tuoi tag; la maggior parte delle risposte qui sotto sono errate perché hai taggato la tua domanda come "SQL" (ora modificata in JPQL) – ChssPly76

+0

No Non voglio includere admin (sysadmin). ProcessUser è un utente e un amministratore di sistema, quindi la mia selezione non mi ottiene quello che voglio. Voglio che l'utente sia ammesso se ha il ruolo sysadmin. –

risposta

17

sintassi corretta JPQL utilizzando subquery:

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

Grazie, questo ha funzionato, ma è corretto WHERE role.name == 'sysadmin' perché stai già dicendo NON IN –

+0

Intendevo così dire role.name = 'sysadmin' –

1

Sarà questo lavoro per te?

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

Questo è l'SQL diretto, non JPQL. – ChssPly76

0

Eseguire una query nidificata. Prima seleziona tutti gli utenti con il ruolo di sysadmin. Quindi seleziona il complemento di questo o tutti gli utenti che non sono in questo risultato.

1

La query restituisce in modo semplice un elenco di utenti/ruoli poiché l'utente ha due ruoli che restituisce due volte, si filtra una riga escludendo il ruolo di "sysadmin". Quello che sembra che tu voglia fare è escludere tutti gli utenti che hanno un ruolo di 'sysadmin' indipendentemente dal fatto che abbiano altri ruoli. Dovresti aggiungere qualcosa alla tua domanda. (Sto andando a Sua richiesta, non tua descrizione)

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

      ) 
+1

Ancora, questo è SQL, non JPQL. – ChssPly76

+0

@ ChssPly76 beh, la speranza è di pubblicare lo sql che lo indicherà nella direzione corretta per correggere il suo JPQL, soprattutto perché nessuno offriva una soluzione JPQL. In realtà non hai postato uno solo fino a 50 minuti dopo che hai sottolineato che le risposte di altri popoli non erano JPQL – Gratzy

+0

Detto "speranza" dovrebbe probabilmente essere menzionato nella tua risposta allora. Nota che non ti ho fatto un downvote; Sto solo sottolineando che questa non è davvero una soluzione valida alla domanda dell'OP. Per quanto riguarda "50 minuti dopo", ho aspettato di vedere se tu o qualcun altro in questo thread avrebbero effettivamente aggiornato le loro risposte dopo aver contenuto JPSQL dopo i miei commenti, così potrò svenderli e ho solo postato la mia risposta dopo quello non è successo. – 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;