Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java NamedEntityGraph-JPA/Hibernate.org.Hibernate.loader.MultipleBagFetchException:无法同时提取多个行李_Java_Hibernate_Jpa - Fatal编程技术网

Java NamedEntityGraph-JPA/Hibernate.org.Hibernate.loader.MultipleBagFetchException:无法同时提取多个行李

Java NamedEntityGraph-JPA/Hibernate.org.Hibernate.loader.MultipleBagFetchException:无法同时提取多个行李,java,hibernate,jpa,Java,Hibernate,Jpa,我们有一个项目,需要惰性地加载一个实体的集合,但在某些情况下,我们需要急切地加载它们。我们在实体中添加了一个@NamedEntityGraph注释。在我们的存储库方法中,我们添加了一个“javax.persistence.loadgraph”提示,以急切地加载上述注释中定义的4个属性。当我们调用该查询时,Hibernate抛出org.Hibernate.loader.MultipleBagFetchException:无法同时提取多个行李 有趣的是,当我将所有这些集合重新定义为急切地获取时,Hi

我们有一个项目,需要惰性地加载一个实体的集合,但在某些情况下,我们需要急切地加载它们。我们在实体中添加了一个
@NamedEntityGraph
注释。在我们的存储库方法中,我们添加了一个“javax.persistence.loadgraph”提示,以急切地加载上述注释中定义的4个属性。当我们调用该查询时,Hibernate抛出
org.Hibernate.loader.MultipleBagFetchException:无法同时提取多个行李

有趣的是,当我将所有这些集合重新定义为急切地获取时,Hibernate确实急切地获取它们,没有多重回迁例外

这是经过提炼的代码。 实体:

@实体
@NamedEntityGraph(name=“Post.Full”,attributeNodes={
@NamedAttributeNode(“评论”),
@名称为三方氮化硼(“plusoners”),
@NamedTributenode(“共享”)
}
)
公营职位{
@OneToMany(cascade=CascadeType.ALL,mappedBy=“postId”)
私人名单评论;
@元素集合
@CollectionTable(name=“post_plusoners”)
私人名单;
@元素集合
@CollectionTable(name=“post\u shared\u with”)
与共享的私有列表;
}
查询方法(全部压缩在一起以便于邮寄):

@覆盖
公共页面findFullPosts(规范规范,可分页){
CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery=builder.createQuery(Post.class);
根post=query.from(post.class);
谓词postsPredicate=spec.toPredicate(post、query、builder);
查询。何处(事后预测);
EntityGraph EntityGraph=entityManager.createEntityGraph(“PlusPost.Full”);
TypedQuery TypedQuery=entityManager.createQuery(查询);
typedQuery.setHint(“javax.persistence.loadgraph”,entityGraph);
setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
Long total=QueryUtils.executeCountQuery(getPostCountQuery(规范));
List

resultList=total>pageable.getOffset()?query.getResultList():集合。

emptyList(); 返回新的PageImpl

(结果列表,可分页,总计); }


关于为什么在实体级别使用即时抓取而不使用动态实体图,有什么提示吗?

我敢打赌,您认为有效的即时抓取实际上是不正确的

当您急切地获取多个“包”(允许重复的无序集合)时,用于执行急切获取(左外部联接)的sql将为联接的关联返回多个结果,如下所述。因此,尽管hibernate不会抛出
org.hibernate.loader.MultipleBagFetchException
,但当您急切地获取多个
列表时,它不会返回准确的结果,原因如上所述

但是,当您向查询提供实体图提示时,hibernate将(正确地)抱怨:

急切抓取本身不是问题,在一个SQL查询中使用多个连接是一个问题。它不仅限于静态抓取策略;它从未被支持(属性),因为它在概念上是不可能的

“非索引”列表或原始集合的大多数用法都是错误的,应该在语义上进行设置

因此,为了让多个急切抓取按您的意愿工作,底线是:

  • 使用
    集合
    而不是
    列表
  • 使用JPA2的
    @OrderColumn
    注释持久化
    列表
    索引
  • 如果所有其他操作都失败,请回退到休眠特定的获取批注(
    FetchMode。选择
    FetchMode。再选择
编辑

相关的:


在@ElementCollection(fetch=FetchType.EAGER)私有设置颜色上,将“列表”更改为“设置”对我来说很有效@ElementCollection(fetch=FetchType.EAGER)私人套装配件;根据Vlad,如果我理解正确,这是一个有问题的答案:
@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);
}