2009-10-16 61 views
11

我有一个非常简单的SQL我需要执行。JPQL,如何不选择东西

我有一个ProcessUser,RoleProcessUserRole表。一个简单的多对多

我想选择所有ProcessUser的也有管理员角色。

但是,我的JPQL失败,因为我的用户也有角色管理员,所以它在列表中检索。

这里是JPQL:

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

生成的SQL是:

 
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

你说你要包括ADMIN的角色,但是您的示例显示ROLE NAME NOT IN SysAdmin。你可以解释吗? – 2009-10-16 15:14:26

+0

@Shervin - 你需要小心你的标签;下面的大多数答案都是不正确的,因为您已将问题标记为“SQL”(现在已更改为JPQL) – ChssPly76 2009-10-16 16:01:25

+0

不,我不想包含管理员(系统管理员)。 ProcessUser是一个用户和一个系统管理员,因此我的选择没有得到我想要的。如果有sysadmin角色,我希望用户被忽略。 – 2009-10-18 14:27:25

回答

17

正确JPQL语法使用子查询(我被你的查询不是你的描述会):

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

谢谢,这几乎工作,但正确的是WHERE role.name =='sysadmin'因为你已经说不在 – 2009-10-18 16:22:30

+0

我的意思是这样说role.name ='sysadmin' – 2009-10-18 16:23:25

1

将这项工作的吗?

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

这是直接的SQL,而不是JPQL。 – ChssPly76 2009-10-16 15:16:50

0

运行嵌套查询。首先选择所有具有sysadmin角色的用户。然后选择这个补充或所有不在此结果中的用户。

1

由于用户有两个角色他回来了两次,所以您的查询基本上是带回用户/角色列表,通过排除“sysadmin”角色筛选出一行。你想要做的就是排除所有具有'sysadmin'角色的用户,而不管他们有其他角色。你需要添加一些东西给你查询。

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

      ) 
+1

再一次,这是SQL,而不是JPQL。 – ChssPly76 2009-10-16 15:56:30

+0

@ ChssPly76很好希望发布sql将指向他正确的方向来修复他的JPQL,尤其是因为没有人提供JPQL解决方案。事实上,在您指出其他人的回复不是JPQL – Gratzy 2009-10-16 16:16:54

+0

之后,您直到50分钟才发布一条。在您的回答中,可能应该提到“希望”。请注意,我没有让你失望;我只是指出,这不是对OP问题的有效解决方案。至于“50分钟后”,我一直在等待看看您或其他人在我的评论后是否会在包含JPSQL后实际更新他们的答案,以便我可以对他们进行提示,并且我只是在发布后回复了我的答案那没有发生。 – ChssPly76 2009-10-16 16:53:11

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;