2009-10-16 17 views
11

Mam dość prosty SQL, który muszę wykonać.JPQL, Jak NIE wybrać czegoś

Mam tabelę ProcessUser, Role i ProcessUserRole. Prostoliniowy wiele-do-wielu

Chcę wybrać wszystkie ProcessUser, które również mają rolę administratora.

Jednak mój JPQL nie działa, ponieważ mój użytkownik ma również funkcję oficera ról, więc jest pobierany na liście.

Oto JPQL:

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

Wygenerowany SQL to:

 
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

Mówisz, że chcesz dołączyć roli ADMIN , ale twój przykład pokazuje ROLE NAME NOT IN SysAdmin. Możesz wytłumaczyć? –

+0

@Shervin - musisz zachować ostrożność przy tagach; większość poniższych odpowiedzi jest niepoprawna, ponieważ oznaczyłeś swoje pytanie jako "SQL" (teraz zmienione na JPQL) – ChssPly76

+0

Nie Nie chcę dołączać administratora (sysadmin). ProcessUser jest użytkownikiem i sysadminem, więc mój wybór nie zapewnia mi tego, czego chcę. Chcę, aby użytkownik został pominięty, jeśli ma rolę sysadmin. –

Odpowiedz

17

prawidłowej składni JPQL użyciem podzapytania:

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

Dzięki, to prawie działało, jednak poprawna jest WHERE rola.nazwa == 'sysadmin', ponieważ już mówisz NIE w –

+0

Miałem na myśli, powiedzmy, role.name = 'sysadmin' –

1

Czy to praca dla Ciebie?

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

To jest prosty kod SQL, a nie JPQL. – ChssPly76

0

Uruchom zagnieżdżone zapytanie. Najpierw wybierz wszystkich użytkowników z rolą sysadmin. Następnie wybierz uzupełnienie tego lub wszystkich użytkowników, którzy nie są w tym wyniku.

1

Twoje zapytanie polega na przywróceniu listy użytkowników/ról, ponieważ użytkownik ma dwie role, z którymi wraca dwa razy, odfiltrowuje jeden wiersz, wykluczając rolę "sysadmin". Wygląda na to, że chcesz wykluczyć wszystkich użytkowników, którzy mają rolę "sysadmin", niezależnie od tego, czy mają inne role. Będziesz musiał dodać coś do zapytania jak. (Idę przez nie zapytaniu opisie)

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

      ) 
+1

To znowu jest SQL, a nie JPQL. – ChssPly76

+0

@ ChssPly76 oraz nadzieja jest umieszczenie sql wskaże mu w poprawnym kierunku, aby naprawić jego JPQL zwłaszcza, ponieważ nikt nie oferował rozwiązania JPQL. W rzeczywistości nie opublikowałeś jednego do 50 minut po tym, jak wskazałeś, że odpowiedzi innych ludzi nie były JPQL – Gratzy

+0

Powiedział, że "nadzieja" powinna być wspomniana w twojej odpowiedzi. Zauważ, że cię nie doceniłem; Po prostu zwracam uwagę, że to nie jest poprawne rozwiązanie problemu OP. Jeśli chodzi o "50 minut po", czekałem, aby sprawdzić, czy ty lub ktokolwiek inny w tym wątku zaktualizuje swoje odpowiedzi po tym, jak zawierają JPSQL po moich komentarzach, więc mogę je przegłosować, a ja wysłałem odpowiedź po to się nie stało. – 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;