【问题标题】:Traversing ORM relationships returns duplicate results遍历 ORM 关系返回重复结果
【发布时间】:2011-06-04 23:38:53
【问题描述】:

我有 4 张桌子 -- store, catalog_galleries, catalog_images, and catalog_financials

当我从store --> catalog_galleries --> catalog_images 遍历关系时,换句话说:store.getCatalogGallery().getCatalogImages() 我得到重复的记录。有谁知道这可能是什么原因?有什么建议去哪里看吗?

store 表与catalog_galleries 具有OneToOne 关系,而catalog_galleries 又与catalog_images 具有OneToMany 关系和一个急切的获取类型。 store 表还具有与 catalog_financialsOneToMany 关系。

以下是相关实体:

商店实体

@Entity
@Table(name="store")  
public class Store {
    ...
    private CatalogGallery gallery;
    ...
    @OneToOne(mappedBy="store")
    public CatalogGallery getGallery() {
        return gallery;
    }
}

目录库实体

@Entity
@Table(name="catalog_galleries")  
public class CatalogGallery {
    ...
    private Store store;
    private Collection<CatalogImage> catalogImages;
    ...
    @OneToOne
    @PrimaryKeyJoinColumn
    public Store getStore() {
        return store;
    }

    @OneToMany(mappedBy="catalogGallery", fetch=FetchType.EAGER)
    public Collection<CatalogImage> getCatalogImages {
        return catalogImages;
    }
}

CatalogImage 实体

@Entity
@Table(name="catalog_images")  
public class CatalogImage {
    ...
    private CatalogGallery catalogGallery;
    ...
    @ManyToOne
    @JoinColumn(name="gallery_id", insertable=false, updatable=false)
    public CatalogGallery getCatalogGallery() {
        return catalogGallery;
    }

}

【问题讨论】:

  • 信息不足,请为您的 JPA 类提供映射。您是否尝试过查看生成的 SQL?
  • 所有记录都是重复的吗?您是否检查过您的连接列是否有重复条目?
  • 是的,所有记录都有重复。在catalog_images 中,join 列中有多个具有相同值的条目,即对相关数据/图像进行分组。
  • 那么,您在数据库中有重复记录,对吧?另外,为什么在 join 列中需要insertable=false, updatable=false
  • @axtavt:数据库本身没有重复记录;但是,catalog_images 的列中的一个字段可能具有相同的值,即对字段进行分组。例如,表中的两行类似于 -- 1 1 comp & 2 1 cat5 -- 第一列是 id,第二列是 gallery_id,第三列是名称。 gallery_id 是连接列,某些行可能具有与该列相同的值。至于是否需要insertable=false,updatable=false,我自己也不太确定;当我运行代码时,我看到一条错误消息,表明我需要添加这些规定

标签: java sql hibernate jpa


【解决方案1】:

如果您正确实现了 equals 和 hashcode 方法并将其存储在 Set 而不是 Collection 中,则问题不大除非重复的数量过多。

【讨论】:

    【解决方案2】:
    1. 您的 getter catalogImages() 不遵循 Java Bean 命名约定。我不确定,但它可能会以某种方式混淆 JPA 提供者。
    2. 通过使用Collection&lt;CatalogImage&gt;,您已明确告诉JPA 提供者允许重复。如前所述,在大多数情况下使用Set 代替Collection 可以解决重复问题,并且可以避免FetchType.EAGER,除非你真的需要它。

    【讨论】:

    • getter 应该是getCatalogImage,代码的原始发布是一个错字。至于切换到Set,我知道这将消除添加重复项,但我不明白为什么从 jpa/hibernate 创建的 sql 查询本身创建重复项。
    • @NKing253,从我的观点来看,这是因为 Store 和 CatalogGallery 之间的一对一关系,或者因为您正在查询两个 Store 的数据集。取决于您的 sql 架构。 JPA 是一个“黑匣子”,查找正在发生的事情的最佳方法是查看生成的 sql。对于休眠使用选项 hibernate.show_sql docs.jboss.org/hibernate/core/3.3/reference/en/html/…
    【解决方案3】:

    这是因为您的fetch = FetchType.EAGER
    Hibernate 创建 JOIN 并尝试通过一次查询获取所有集合。
    如果您确实需要 FetchType.EAGER 并且不想用 Set 替换您的集合,您可以为您的集合使用 @Fetch (FetchMode.SELECT) 注释:

    @OneToMany(mappedBy="catalogGallery", fetch=FetchType.EAGER)
    @Fetch (FetchMode.SELECT)
    public Collection<CatalogImage> getCatalogImages {
        return catalogImages;
    }
    

    欲了解更多信息,请参阅post

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      • 2021-09-06
      • 2015-11-25
      • 1970-01-01
      相关资源
      最近更新 更多