本文介绍了NamedEntityGraph - JPA / Hibernate抛出org.hibernate.loader.MultipleBagFetchException:不能同时获取多个包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个项目,我们需要懒惰地加载一个实体的集合,但在某些情况下,我们需要它们急切地加载。我们已经为我们的实体添加了一个 $ c>而不是 List

  • 使用JPA保持 List 2的 @OrderColumn 注释,
  • 如果一切都失败,则回退到Hibernate特定的提取注释( FetchMode.SELECT 或 FetchMode.SUBSELECT )



  • 编辑



    相关:





    We have a project where we need to lazily load collections of an entity, but in some cases we need them loaded eagerly. We have added a @NamedEntityGraph annotation to our entity. In our repository methods we add a "javax.persistence.loadgraph" hint to eagerly load 4 of attributes defined in said annotation. When we invoke that query, Hibernate throws org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags.

    Funnily, when I redefine all of those collection as eagerly fetched Hibernate does fetch them eagerly with no MultipleBagFetchException.

    Here is the distilled code.Entity:

    @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;
    
    }
    

    Query method (all cramped together to make it postable):

    @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);
    }
    

    Any hints on why is this working with eager fetches on entity level, but not with dynamic entity graphs?

    解决方案

    I'm betting the eager fetches you think were working, were actually working incorrectly.

    When you eager fetch more than one "bag" (an unorder collection allowing duplicates), the sql used to perform the eager fetch (left outer join) will return multiple results for the joined associations as explained by this SO answer. So while hibernate does not throw the org.hibernate.loader.MultipleBagFetchException when you have more than one List eagerly fetched it would not return accurate results for the reason given above.

    However, when you give the query the entity graph hint, hibernate will (rightly) complain. Hibernate developer, Emmanuel Bernard, addresses the reasons for this exception to be thrown:

    Emmanuel goes on to say in a different JIRA comment that,

    So bottom line, in order to get the multiple eager fetching to work as you desire:

    • use a Set rather than a List
    • persist the List index using JPA 2's @OrderColumn annotation,
    • if all else fails, fallback to Hibernate specific fetch annotations (FetchMode.SELECT or FetchMode.SUBSELECT)

    EDIT

    related:

    这篇关于NamedEntityGraph - JPA / Hibernate抛出org.hibernate.loader.MultipleBagFetchException:不能同时获取多个包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    10-16 08:45