Jpa JPQL,如何不选择某些内容

Jpa JPQL,如何不选择某些内容,jpa,jpql,Jpa,Jpql,我需要执行一个非常简单的SQL 我有一个ProcessUser、Role和一个ProcessUserRole表。直接的多对多 我想选择所有同样具有管理员角色的ProcessUser 然而,我的JPQL失败了,因为我的用户也有角色管理器,所以在列表中检索它 以下是JPQL: entityManager.createQuery("SELECT p FROM " + ProcessUser.class.getName() + " p join p.roles role WHERE role.na

我需要执行一个非常简单的SQL

我有一个
ProcessUser
Role
和一个
ProcessUserRole
表。直接的多对多

我想选择所有同样具有管理员角色的
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' ) ) 选择 不同的进程use0.id作为id8, 进程0位置为位置8, processuse0。用户名为username8, processuse0.organization作为organization 9.8, processuse0\u.passwordHash作为密码4\u 8\u, processuse0\u0.fromEmail作为fromEmail8\u0, processuse0\u0.firstname作为firstname8\u0, processuse0。lastname作为lastname8, processuse0\将进程作为进程8_ 从…起 ProcessUser processuse0\u 内连接 ProcessUserRoles角色1\u 在processuse0\u0.id=roles1\u0.userId上 内连接 角色2_ 角色1上的角色id=角色2上的角色id 哪里 ( 角色2。名称不在( “系统管理员” ) )
这对你有用吗

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

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

您的查询基本上是返回一个用户/角色列表,因为您的用户有两个角色他返回两次,您可以通过排除“sysadmin”角色过滤掉一行。听起来您想要做的是排除所有具有“sysadmin”角色的用户,而不管他们是否具有其他角色。您需要向查询中添加类似的内容。(我是根据你的询问而不是你的描述)


使用子查询的正确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'
 )
JPQL:

TypedQuery query=em.createQuery(“”+
“从ProcessUser p中选择p”+
“其中p.roles.name?1”,ProcessUser.class);
setParameter(1,“sysadmin”);
return query.getResultList;

您说希望包含一个ADMIN角色,但示例中显示的角色名称不在SysAdmin中。你能解释一下吗?@Shervin-你需要小心你的标签;下面的大多数答案都不正确,因为您已经将问题标记为“SQL”(现在改为JPQL)不,我不想包括admin(sysadmin)。ProcessUser是一个用户,也是一个系统管理员,因此我的选择不能满足我的需要。如果用户具有sysadmin角色,我希望用户被告知。这是纯SQL,而不是JPQL。同样,这是SQL,而不是JPQL。@ChssPly76希望发布SQL将为他指明修复JPQL的正确方向,特别是因为没有人提供JPQL解决方案。事实上,直到你指出其他人的回答不正确50分钟后,你才发布了一篇文章。当时,你的回答中应该提到“希望”。请注意,我没有投你反对票;我只是指出,这并不是OP问题的有效解决方案。到“50分钟后”为止,我一直在等待,看你或该线程中的任何其他人是否会在我的评论之后更新他们的答案,以包含JPSQL,这样我就可以对他们进行投票,并且我只在没有发生后发布我的答案。@ChssPly76他列出了生成的sql并将问题标记为sql,你怎么知道他不是在寻求帮助理解生成的sql?也许你不应该删除sql标记。谢谢你,格雷兹。我实际上在寻找jpql,但是sql也很好,因为我可以将其转换为jpql。谢谢。谢谢,这几乎奏效了,但是role.name='sysadmin'的位置是正确的,因为您已经在说NOT INI的意思是说role.name='sysadmin'
SELECT p FROM ProcessUser p
 WHERE p.id  NOT IN (
  SELECT p2.id FROM ProcessUser p2
    JOIN p2.roles role
   WHERE role.name='sysadmin'
 )
TypedQuery<ProcessUser> query = em.createQuery("" +  
   " SELECT p FROM ProcessUser p " +
   " WHERE p.roles.name <> ?1", ProcessUser.class);
query.setParameter(1, "sysadmin");
return query.getResultList;