当前位置: 首页 > 面试题库 >

为什么在CriteriaQuery上左联接不筛选结果?

夏侯和韵
2023-03-14
问题内容

我有两个实体,UserRoles每一个与活跃布尔参数和ManyToMany关系。

此布尔参数用于逻辑删除。

当我在下面运行此查询时,为什么结果中包含不活动的角色?

 CriteriaBuilder builder = em.getCriteriaBuilder();
 CriteriaQuery<User> query = builder.createQuery(User.class);

 //Select
 Root<User> user = query.from(User.class);

 //Join
 SetJoin<User, Role> role = user.joinSet("roles", JoinType.LEFT);
 Predicate rolesActivePredicate = builder.isTrue(role.get("active"));
 role.on(rolesActivePredicate);

 query.multiselect(user).distinct(true);

 //Where
 Predicate usernamePredicate = builder.equal(user.get("username"), username);
 Predicate activePredicate = builder.isTrue(user.get("active"));
 query.where(usernamePredicate, activePredicate);

 TypedQuery<UnikUser> typedQuery = em.createQuery(query);
 return Optional.of(typedQuery.getSingleResult());

问题答案:
  1. 考虑以下Users与的@OneToMany关系Role

    User-1 : Active-Role-1, Active-Role-2, In-Active-Role-3
    User-2 : In-Active-Role-3
    User-3 : Active-Role-1, Active-Role-2

  2. JPA首先找到User满足您条件的记录(至少有一个活跃角色)

    User-1
    User-3

  3. 这就是您的条件在哪里结束的地方 。一旦确定要获取的记录ID,JPA就会User完整获取这些记录。User-1及其User-3所有相关角色(包括不活动的角色)。它可能会执行join或执行另一项操作,select但是无论何时执行,它都会获取其所有关联字段

  4. 总而言之,一旦决定提取entity便无法对其关联的字段进行任何过滤 。在这种情况下,您希望在其中过滤一个对象,user.getRoles()但不能。

  5. 如果JPA允许这样做dirty checking,则不能这样做,cascading或者repeatable read。所以它不允许



 类似资料:
  • 问题内容: 我们有下面的查询。使用LEFT OUTER联接需要9秒钟才能执行。将LEFT OUTER更改为LEFT INNER可以将执行时间减少到2秒,并且返回 相同 数量的行。由于正在处理dbo.Accepts表中相同数量的行,而不论联接类型如何,为什么外层要花3倍的时间? 问题答案: 返回相同行数的事实是事后事实,查询优化器无法预先知道Accepts中的每一行在Marker中都有匹配的行,可以

  • 问题内容: 您可以运行此命令并告诉我为什么结果集只有两行吗?它应该有三个,看起来像这样… 这是sql,因此您可以将其粘贴到查询工具中 我无法弄清楚为什么#appSteps中的所有3个非空行都没有返回 问题答案: 原因是因为您在子句中包含了右侧表。您应该将其移至以下条件: 这样做的原因是,该子句是 在后面 进行评估的,然后从中过滤出您的结果。 在子句中包含的右手表(或的左手表)可将转换为。

  • 带hibernate的JSF应用程序 有没有一种方法可以使用联接来过滤条件列表返回的结果<我有两张桌子。订单和顾客。 我需要返回丢失电子邮件地址的客户的所有订单,以及所有order.billingCustomeId=null和CustomeId=nullorder.shipping订单。 客户可以在或上进行匹配。 我将使用的SQL Hibernate标准 这将返回billing/shipping

  • 问题内容: 我没有抱怨,只是想知道。为什么Java用绘图表面的左上点作为原点?我认为更自然的是选择左下角作为原点,并在它们向上和向右时增加轴(类似于Quartz)。 问题答案: 自时间开始以来,计算机图形学的起源就在左上角,其中包括QuickDraw。使用左下角(如数学中一样)是PostScript / PDF。由于Quartz基于PDF,因此它使用其坐标,但这主要是图形库中的唯一决定。

  • 问题内容: 以两个表为例:和。 列出产品详细信息,包括名称和ID,同时列出涉及产品的交易,包括日期,产品ID,客户等。 我需要显示一个网页,其中显示10个产品,每个产品的最近5个交易。到目前为止,如果mysql允许该部分,则似乎没有任何查询有效,并且下面的子查询也可以工作( 在“ where子句”中 出现 Unknown列“ ta.product_id”的 失败 :[ERROR:1054] )。

  • 我在文件里找不到具体的东西(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-方法。查询创建)和一些博客中没有令人满意的答案。所以这里是我的问题。 我有如下表格实体: 以及用户表实体: 现在,我想在我的存储库中有这样一个查询: 意味着我想通过我的工作站实体找到所有年龄在一定年龄以下的用户。 如