【问题标题】:Why Hibernate Duplicates Objects Though DB Tables Do Not Include Duplicated Rows?为什么 Hibernate 复制对象,而 DB 表不包含重复的行?
【发布时间】:2015-02-24 22:53:49
【问题描述】:

当我从数据库中检索数据时,结果集包含重复项 - 完全相同的对象(ID 也相同)。我想知道是什么原因以及如何处理。正如我在标题中提到的,数据库表只包含唯一的行。

【问题讨论】:

  • 您能发布您的 HQL 查询和映射吗?

标签: java hibernate orm mapping duplicates


【解决方案1】:

我猜你的 kittens 表是两个不同表的集合属性,如果是,你必须在你的集合字段上方添加这个注释

@Fetch(FetchMode.SUBSELECT)

【讨论】:

  • 这让我发疯了 - 谢谢你,完美的工作
【解决方案2】:

如果您在相关集合上创建连接,就会发生这种情况。例如,如果我们确实遵循文档:

17.4. Associations

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

避免这种情况的方法是:

  • 不加入集合 - 使用批量加载
  • 使用 ResultTransformer

同时检查:

小引用:

使用批量获取,如果访问一个代理,Hibernate 可以加载多个未初始化的代理。批量抓取是对惰性选择抓取策略的优化。您可以通过两种方式配置批量获取:在类级别和集合级别。

类/实体的批量获取更容易理解。考虑以下示例:在运行时,您在 Session 中加载了 25 个 Cat 实例,每个 Cat 都有对其所有者的引用,即一个 Person。 Person 类使用代理lazy="true" 进行映射。如果您现在遍历所有猫并在每个猫上调用 getOwner(),默认情况下,Hibernate 将执行 25 个 SELECT 语句来检索代理的所有者。您可以通过在 Person 的映射中指定批量大小来调整此行为:

<class name="Person" batch-size="10">...</class>

使用批量大小,我们的集合被延迟加载(不是作为主查询的一部分),但它们不会触发 1 + N 问题,因为它们是批量加载的。我会投票支持这个解决方案。然后根查询可以很容易地用于分页(没有重复)

【讨论】:

    猜你喜欢
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-27
    相关资源
    最近更新 更多