Hibernate不允许获取一个以上的包,因为这会生成Cartesian。
现在,您会发现很多答案,博客文章,视频或其他资源,它们告诉您对集合使用a Set
代替List
。
使用Sets
而不是Lists
将MultipleBagFetchException
消失,但笛卡尔积仍将存在。
而不是JOIN FETCH
在单个JPQL或Criteria API查询中使用多个查询:
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
,就可以了。通过使用多个查询,您将避免使用笛卡尔积,因为除第一个集合外,其他任何集合都是使用辅助查询来获取的。