以下是我的代码在这里,我使用多个列表从数据库中获取数据。从hql查询中获取数据时显示异常。
Pojo课
public class BillDetails implements java.io.Serializable { private Long billNo; // other fields @LazyCollection(LazyCollectionOption.FALSE) private List<BillPaidDetails> billPaidDetailses = new ArrayList<BillPaidDetails>(); private Set productReplacements = new HashSet(0); @LazyCollection(LazyCollectionOption.FALSE) private List<BillProduct> billProductList = new ArrayList<BillProduct>(); //getter and setter }
hmb.xml文件
<class name="iland.hbm.BillDetails" table="bill_details" catalog="retail_shop"> <id name="billNo" type="java.lang.Long"> <column name="bill_no" /> <generator class="identity" /> </id> <bag name="billProductList" table="bill_product" inverse="true" lazy="false" fetch="join"> <key> <column name="bill_no" not-null="true" /> </key> <one-to-many class="iland.hbm.BillProduct" /> </bag> <bag name="billPaidDetailses" table="bill_paid_details" inverse="true" lazy="false" fetch="select"> <key> <column name="bill_no" not-null="true" /> </key> <one-to-many class="iland.hbm.BillPaidDetails" /> </bag> <set name="productReplacements" table="product_replacement" inverse="true" lazy="false" fetch="join"> <key> <column name="bill_no" not-null="true" /> </key> <one-to-many class="iland.hbm.ProductReplacement" /> </set> </class>
HQL查询
String hql = "select distinct bd,sum(bpds.amount) from BillDetails as bd " + "left join fetch bd.customerDetails as cd " + "left join fetch bd.billProductList as bpd " + "left join fetch bpd.product as pd " +"left join fetch bd.billPaidDetailses as bpds " + "where bd.billNo=:id " + "and bd.client.id=:cid ";
我正在尝试以下查询从数据库中获取数据,但这显示了 org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags 如何解决此问题
org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
这是一个非常常见的问题,所以我决定将答案变成一篇文章。
Hibernate不允许获取一个以上的包,因为这会生成Cartesian。
现在,您会发现很多答案,博客文章,视频或其他资源,它们告诉您对集合使用a Set代替List。
Set
List
那是可怕的建议!
使用Sets而不是Lists将MultipleBagFetchException消失,但笛卡尔积仍将存在。
Sets
Lists
MultipleBagFetchException
而不是JOIN FETCH在单个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,就可以了。通过使用多个查询,您将避免使用笛卡尔积,因为除第一个集合外,其他任何集合都是使用辅助查询来获取的。