【发布时间】:2015-02-24 22:53:49
【问题描述】:
当我从数据库中检索数据时,结果集包含重复项 - 完全相同的对象(ID 也相同)。我想知道是什么原因以及如何处理。正如我在标题中提到的,数据库表只包含唯一的行。
【问题讨论】:
-
您能发布您的 HQL 查询和映射吗?
标签: java hibernate orm mapping duplicates
当我从数据库中检索数据时,结果集包含重复项 - 完全相同的对象(ID 也相同)。我想知道是什么原因以及如何处理。正如我在标题中提到的,数据库表只包含唯一的行。
【问题讨论】:
标签: java hibernate orm mapping duplicates
我猜你的 kittens 表是两个不同表的集合属性,如果是,你必须在你的集合字段上方添加这个注释
@Fetch(FetchMode.SUBSELECT)
【讨论】:
如果您在相关集合上创建连接,就会发生这种情况。例如,如果我们确实遵循文档:
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%") )
.createCriteria("kittens")
.add( Restrictions.like("name", "F%") )
.list();
我们加入猫和它的小猫。如果有更多的小猫与一只猫相关,从 F% 开始,我们得到结果:
Cat 1 - Kitten 1
Cat 1 - Kitten 2
Cat 2 - Kitten 3
Cat 2 - Kitten 4
避免这种情况的方法是:
同时检查:
小引用:
使用批量获取,如果访问一个代理,Hibernate 可以加载多个未初始化的代理。批量抓取是对惰性选择抓取策略的优化。您可以通过两种方式配置批量获取:在类级别和集合级别。
类/实体的批量获取更容易理解。考虑以下示例:在运行时,您在 Session 中加载了 25 个 Cat 实例,每个 Cat 都有对其所有者的引用,即一个 Person。 Person 类使用代理lazy="true" 进行映射。如果您现在遍历所有猫并在每个猫上调用 getOwner(),默认情况下,Hibernate 将执行 25 个 SELECT 语句来检索代理的所有者。您可以通过在 Person 的映射中指定批量大小来调整此行为:
<class name="Person" batch-size="10">...</class>
使用批量大小,我们的集合被延迟加载(不是作为主查询的一部分),但它们不会触发 1 + N 问题,因为它们是批量加载的。我会投票支持这个解决方案。然后根查询可以很容易地用于分页(没有重复)
【讨论】: