我们有一个项目,需要延迟加载实体的集合,但在某些情况下,我们需要急切地加载它们。我们添加了一个@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);
}
关于为什么这适用于实体级别的急切提取,但不适用于动态实体图,有什么提示吗?