我有以下实体结构:业务 - >营销活动 - >促销,其中一个业务可以有许多营销活动,一个营销活动可以有许多促销活动。两个一对多关系都被声明为 LAZY。在我的代码中的一处,我需要急切地从 Business 中获取这两个集合,所以我这样做:
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:无法同时获取多个包”异常。然后我用谷歌搜索了这个异常,看起来我必须使用 Set,而不是 List。所以我将集合更改为 Set 并且它起作用了。有人能告诉我为什么 List 在这种情况下不起作用吗?
我期望查询返回单个结果,因为它正在查询 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 无法知道重复的对象是由连接引起的还是由子表中的实际重复数据引起的。看着this http://www.jroller.com/eyallupu/entry/hibernate_exception_simultaneously_fetch_multiple以获得一个很好的解释。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)