Hibernate不允许获取多个包,因为这会生成笛卡尔积,对于无序列表,在Hibernate术语中称为baggs,这将导致重复条目,即使底层集合没有这些重复的行。因此,休眠只是在编译 JPQL 查询时防止了这种情况。
现在,您会发现许多答案,博客文章,视频或其他资源,告诉您对集合使用a而不是a。Set
List
这是一个可怕的建议。别这样!
使用而不是会使消失,但笛卡尔积仍然存在。Sets
Lists
MultipleBagFetchException
正确的修复
而不是在单个 JPQL 或 Criteria API 查询中使用多个:JOIN FETCH
List<Post> posts = entityManager
.createQuery(
"select p " +
"from Post p " +
"left join fetch p.comments " +
"left join fetch p.tags " +
"where p.id between :minId and :maxId", Post.class)
.setParameter("minId", 1L)
.setParameter("maxId", 50L)
.getResultList();
您可以执行以下技巧:
List<Post> posts = entityManager
.createQuery(
"select distinct p " +
"from Post p " +
"left join fetch p.comments " +
"where p.id between :minId and :maxId ", Post.class)
.setParameter("minId", 1L)
.setParameter("maxId", 50L)
.setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
.getResultList();
posts = entityManager
.createQuery(
"select distinct p " +
"from Post p " +
"left join fetch p.tags t " +
"where p in :posts ", Post.class)
.setParameter("posts", posts)
.setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
.getResultList();
只要您最多使用 获取一个集合,就可以了。通过使用多个查询,您将避免笛卡尔积,因为任何其他集合,但第一个集合是使用辅助查询获取的。JOIN FETCH