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

NamedEntityGraph-JPA /Hibernate抛出org.hibernate.loader.MultipleBagFetchException:无法同时获取多个包

乜璞瑜
2023-03-14
问题内容

我们有一个项目,需要延迟加载实体的集合,但是在某些情况下,我们需要热切地加载它们。我们已经@NamedEntityGraph为实体添加了注释。在我们的存储库方法中,我们添加了一个“
javax.persistence.loadgraph”提示来热切加载上述注释中定义的4个属性。当我们调用该查询时,Hibernate抛出org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

有趣的是,当我重新定义所有这些集合时,Hibernate 确实不 使用MultipleBagFetchException来 获取它们

这是摘要代码。实体:

@Entity
@NamedEntityGraph(name = "Post.Full", attributeNodes = {
        @NamedAttributeNode("comments"),
        @NamedAttributeNode("plusoners"),
        @NamedAttributeNode("sharedWith")
    }
)
public class Post {
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "postId")
    private List<Comment> comments;

    @ElementCollection
    @CollectionTable(name="post_plusoners")
    private List<PostRelatedPerson> plusoners;

    @ElementCollection
    @CollectionTable(name="post_shared_with")
    private List<PostRelatedPerson> sharedWith;

}

查询方法(全部局促在一起以使其可发布):

@Override
public Page<Post> findFullPosts(Specification<Post> spec, Pageable pageable) {
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Post> query = builder.createQuery(Post.class);
    Root<Post> post = query.from(Post.class);
    Predicate postsPredicate = spec.toPredicate(post, query, builder);
    query.where(postsPredicate);

    EntityGraph<?> entityGraph = entityManager.createEntityGraph("PlusPost.Full");

    TypedQuery<GooglePlusFullPost> typedQuery = entityManager.createQuery(query);
    typedQuery.setHint("javax.persistence.loadgraph", entityGraph);

    query.setFirstResult(pageable.getOffset());
    query.setMaxResults(pageable.getPageSize());

    Long total = QueryUtils.executeCountQuery(getPostCountQuery(specification));

    List<P> resultList = total > pageable.getOffset() ? query.getResultList() : Collections.<P>emptyList();
    return new PageImpl<P>(resultList, pageable, total);
}

有什么暗示为什么这与在实体级别进行热切获取而不是在动态实体图上起作用有关?


问题答案:

我敢打赌,您认为工作正常,实际工作不正确的渴望。

当您渴望获取多个“
bag”(允许重复的无序集合)时,用于执行渴望获取(左外部联接)的sql将为联接的关联返回多个结果,如该SO答案所述。因此,org.hibernate.loader.MultipleBagFetchException当您List渴望获取多个时,hibernate不会抛出,但由于上述原因,它不会返回准确的结果。

但是,当您向查询提供实体图提示时,hibernate将(正确地)抱怨。 hibernate开发人员Emmanuel
Bernard解决了抛出此异常的原因

渴望获取本身并不是问题,而是在一个SQL查询中使用多个联接。它不仅仅限于静态获取策略。它从未得到支持(属性),因为从概念上讲是不可能的。

伊曼纽尔在JIRA的另一则评论中说:

“非索引”列表或原始Collection的大多数用法是错误的,在语义上应为Set。

因此,最重要的是,为了使多个热切的获取工作如您所愿:

  • 使用Set而不是List
  • List使用JPA 2的@OrderColumn注释保留索引
  • 如果所有其他方法均失败,则回退到Hibernate特定的获取批注(FetchMode.SELECTFetchMode.SUBSELECT


 类似资料:
  • 问题内容: 以下是我的代码在这里,我使用多个列表从数据库中获取数据。从hql查询中获取数据时显示异常。 Pojo课 hmb.xml文件 HQL查询 我正在尝试以下查询从数据库中获取数据,但这显示了 如何解决此问题 问题答案: 这是一个非常常见的问题,所以我决定将答案变成一篇文章。 Hibernate不允许获取一个以上的包,因为这会生成Cartesian。 现在,您会发现很多答案,博客文章,视频或其

  • 问题内容: Hibernate在创建SessionFactory时抛出此异常: org.hibernate.loader.MultipleBagFetchException:无法同时获取多个包 这是我的测试用例: Parent.java Child.java 这个问题怎么样?我能做什么? 编辑 好的,我的问题是另一个“父”实体在我的父内部,我的真实行为是这样的: Parent.java Anoth

  • 问题内容: 在创建时抛出此异常: 无法同时获取多个包 这是我的测试用例: Parent.java 这个问题怎么样?我能做什么? 编辑 好的,我的问题是另一个“父”实体在我的父内部,我的真实行为是这样的: Parent.java AnotherParent.java Hibernate不喜欢带有的两个集合FetchType.EAGER,但这似乎是一个错误,我没有做不寻常的事情… FetchType.

  • 无效数据访问设备别名:org.hibernate.loader.多个包取出异常:无法同时获取多个包: [订单项, 订单项选项]; 上面是我加入下面三个表时遇到的一个例外。 OrderItemOption.java 订单项.java 订单.java 这是我一次性加入它们的QueryDSL代码。 我想做的是获得包含过滤关系的order对象,这样我就可以通过Order对象访问过滤的子对象。并且关系的类型

  • 我有以下实体 注册程序 教练 官方 基本上,我有与(Trainer-Register steredProgram,官方注册程序)有多对一关系的实体。现在我有一个服务已经满足了我的要求,通过id获取注册程序,我应该只包含所有的和与isDeletedfalse。请参阅下面的服务: 服务 现在,我尝试使用< code>@Query和< code>@EntityGraph,这样我就可以只使用一个查询就获得

  • 我想点击类id为clsArrowClick的锚标记,并且相同的id在另一个锚标记上。 我尝试了list、wait方法和simple way方法,但我的程序在线程“main”org.openqa.selenium.ElementNotVisibleException中抛出了一个错误异常 就像 //WebDriverWait wait=new WebDriverWait(驱动程序,30);//wait