这是一个非常常见的问题,所以我决定将答案变成一篇文章。
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();只要您使用最多获取一个集合
JOINFETCH,就可以了。通过使用多个查询,您将避免使用笛卡尔积,因为除第一个集合外,其他任何集合都是使用辅助查询来获取的。



