JPQL, wie man nicht etwas auswählt
Frage
Ich habe eine ziemlich einfache SQL, die ich ausführen muss.
Ich habe ein ProcessUser
, Role
und ein ProcessUserRole
Tisch. Ein geradliniger Vieler zu viel zu vielen
Ich möchte alle auswählen ProcessUser
Das hat auch eine Rolle von Admin.
Mein JPQL schlägt jedoch fehl, weil mein Benutzer auch Rollenbeauftragte hat und in der Liste abgerufen wird.
Hier ist der JPQL:
entityManager.createQuery("SELECT p FROM " + ProcessUser.class.getName()
+ " p join p.roles role WHERE role.name NOT IN ('sysadmin')").getResultList();
Das erzeugte SQL ist:
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' ) )
Lösung
Richtige JPQL -Syntax mit Unterabfrage:
SELECT p FROM ProcessUser p
WHERE p.id NOT IN (
SELECT p2.id FROM ProcessUser p2
JOIN p2.roles role
WHERE role.name='sysadmin'
)
Andere Tipps
Wird das für Sie funktionieren?
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'
)
Ihre Abfrage bringt grundlegend eine Liste von Benutzern/Rollen zurück, da Ihr Benutzer zwei Rollen hat, die er zweimal zurückkommt. Sie filtern eine Zeile heraus, indem Sie die Rolle von 'sysadmin' ausschließen. Was es so hört, als ob Sie es tun möchten, ist, alle Benutzer auszuschließen, die eine Rolle bei "Sysadmin" spielen, unabhängig davon, ob sie andere Rollen haben. Sie müssten Ihnen eine Frage hinzufügen, wie Sie es wie ein Anfragen hinzufügen müssen. (Ich gehe durch deine Frage nicht deine Beschreibung)
where processuse0_.id not in
select ( userId from
ProcessUserRoles
inner join
Role
on ProcessUserRoles.roleId=Role.id
where role.name != 'sysadmin'
)
Eine verschachtelte Anfrage durchführen. Wählen Sie zunächst alle Benutzer mit der Rolle von Sysadmin. Wählen Sie dann die Ergänzung oder alle Benutzer, die nicht in diesem Ergebnis sind.
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;