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

标准渴望获取联接集合,以避免n + 1个选择

汪迪
2023-03-14
问题内容

假设项目和出价是实体:一个项目有很多出价。它们在 Hibernate 中以典型的父/子关系映射:

<class name="Item" table="ITEM">
  ...
  <set name="bids" inverse="true">
    <key column="ITEM_ID"/>
    <one-to-many class="Bid"/>
  </set>
</class>

在执行此查询后尝试访问每个项目的出价时,如何避免n + 1个选择?

List<Item> items = session.createCriteria(Item.class)
                        .createAlias("bids", "b").
                        .add(Restrictions.gt("b.amount", 100)).
                        .list();

请注意, 我需要 急切 的竞标价格,但 对收款 要有 进一步的限制 (b.amount> 100)

我尝试了以下失败:

List<Item> items = session.createCriteria(Item.class)
                        .setFetchMode("bids", FetchMode.JOIN).
                        .createAlias("bids", "b").
                        .add(Restrictions.gt("b.amount", 100)).
                        .list();

List<Item> items = session.createCriteria(Item.class)
                        .createCriteria("bids")
                        .add(Restrictions.gt("amount", 100)).
                        .list();

问题答案:

这说明了为什么对fetch-joined集合添加限制会导致集合未初始化( 请注意 ,没有限制的同一查询会为集合急切地获取数据):

“如果表A和B之间的关系为1:n,并且对B添加了限制,并且希望能尽快获取它,那么问题是当您要从A导航到B时会发生什么。只查看B中符合限制条件的数据,还是应该查看与A相关的所有B?”
在这里看到更多…

但是,使用HQL代替标准,部分获取出价集合

List<Item> items = session.createQuery(
          "from Item i left join fetch i.bids b where b.amount > :amount")
          .setParameter("amount", 100)
          .list();

在我看来,这是不一致的,但这就是它的工作原理

顺便说一句,如果您需要的是父母及其所有子女的清单,而仅是其子女都满足一定限制的父母,那么您可以使用此清单

List<Item> items = session.createQuery(
          "from Item i left join fetch i.bids b " +
          "where not exists (from Bid b where b.item = i and b.amount <= :amount)")
          .setParameter("amount", 100)
          .list();


 类似资料:
  • 问题内容: 我有以下课程: 现在,我基本上想加载all ,但在适用时渴望加载条,所以我使用以下查询: 在这种情况下,似乎为Bar实体产生了SELECT N + 1问题: 是否可以告诉hibernate急切地为子集合中的每个元素加载一个关联,而无需诉诸N + 1 SELECT? 我尝试了以下查询,但由于它是一个集合,因此显然无法正常工作: 我也尝试使用,虽然这使我可以引用子集合,但似乎并没有急于加载

  • 问题内容: 我有四个表: 和类似的实体结构: 我需要一个查询将返回所有与它在表和孩子初始化。该是预先抓取,但孩子们是懒牵强。 我知道如何编写查询,将查询表的直接子级并相应地对其进行初始化。但是,我不知道如何获取从顶层表急切获取的表的子级。 我已经尝试过类似的东西: 但是,这总是给我一个错误,即所有者不是SELECT的一部分。 任何帮助是极大的赞赏。 问题答案: Hibernate参考 我们可能需要

  • 我有以下课程: 现在我基本上想加载所有的,但在适用时渴望加载条,所以我使用以下查询: 虽然这是可行的,但它似乎为Bar实体生成了一个SELECT N 1问题: 有没有可能告诉hibernate急切地为子集合中的每个元素加载关联,而不使用N 1 SELECTs? 我尝试了以下查询的思路,这显然不起作用,因为它是一个集合: 我还尝试在(b.bar)bar中使用

  • 问题内容: 我有一个我认为应该很普遍的问题,但找不到答案。 我有2个对象:组和用户。我的课程如下所示: 现在,当我尝试从数据库中获取用户时,它带来了所有组,所有组都带来了所有用户,依此类推。最后,我遇到了stackoverflow异常。 如何解决此问题,并且仍然具有双向关联以及到达列表中对象的能力? 问题答案: 如果使用属性(无论如何都应使用)将双向关联的一侧设为关联的 拥有 侧,是否会遇到相同的

  • 朋友们!我有这些实体: 文件: 所以,当我想用changeNotices获取文档时,这不是问题,我只有一个选择。但是当我想用文档获取ChangeNotice时,我有(n+1),首先是文档,n是changeNotices map。 我在查询中使用join fetch,但没有帮助。我认为问题在于,在文档中我有map ,其中实体是一个值,我应该使用@manytomany关系。在ChangeNotice中

  • 我在JavaEE(泽西)与JPA的应用程序,我有一个问题与未初始化的实体。我有3个实体汽车,业主,房子,汽车可以有多个业主和业主可以有多个房子。当我返回(entityManager.find)汽车然后车主被初始化。当我返回房子然后业主初始化,但车不是。我希望能够调用House.getOwner(). getCar(). getId()。现在我必须打电话给House,然后打电话给Owner以获得Ca