我有以下实体结构:业务 - >广告系列 - >促销,其中一个业务可以有多个广告系列,一个广告系列可以有多个促销.一对多关系都被宣布为LAZY.我的代码中有一个位置,我需要急切地从业务中获取这两个集合,所以我这样做:
Query query = entityManager.createQuery("select b from Business b " + "left join fetch b.campaigns c " + "left join fetch c.promotions where b.id=:id"); query.setParameter("id", b.getId()); business = (Business) query.getResultList().get(0);
但是,查询返回一个结果列表,其中包含4个Business对象,所有4个对象都引用同一个Business实例.在我的数据库中,此商家下面有3个广告系列,所有3个广告系列都有3个广告系列.
我有两个问题:
首先,我使用List来包含关系的多方面,但是当程序运行时,我得到"org.hibernate.HibernateException:不能同时获取多个包"的异常.然后我用Google搜索了这个异常,看起来我必须使用Set而不是List.所以我将集合更改为Set并且它有效.有人能告诉我为什么列表在这种情况下不起作用?
我期望查询返回单个结果,因为它查询id,这是主键,因此只应返回单个结果.但事实证明它返回List中的4个实例.这是一个问题吗?或者这是预期的行为?
任何帮助将不胜感激.
生成的sql看起来像:
select * from Business b left outer join campaigns c on c.business_id = b.id left join promotions p on p.campaign_id = c.id where b.id=:id
在内部,Hibernate只有一个Business实例,但重复项将保留在结果集中.这是预期的行为.您需要的行为可以通过使用DISTINCT子句或使用LinkedHashSet来过滤结果来实现:
Collection result = new LinkedHashSet(query.getResultList());
这将只返回唯一的结果,保留插入顺序.
每当您尝试以有序的方式(可能是重复的项目)急切地获取多个集合时,就会发生"org.hibernate.HibernateException:无法同时获取多个行李".如果考虑生成的SQL,这有意义.Hibernate无法知道重复对象是由连接引起的还是由子表中的实际重复数据引起的.看看这个是一个很好的解释.