遍历ORM关系会返回重复的结果

时间:2011-01-06 22:51:18

标签: java sql hibernate jpa

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

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

store表格与OneToOne的{​​{1}}关系,catalog_galleriesOneToMany的关系为catalog_images,并且是一种急切的提取类型。 store表格与OneToMany的关系也为catalog_financials

以下是相关实体:

存储实体

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

CatalogGallery实体

@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;
    }

}

3 个答案:

答案 0 :(得分:5)

这是因为你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

答案 1 :(得分:0)

如果正确实现equals和hashcode方法并存储在Set而不是Collection中,那么不会出现问题,除非重复数量过多。

答案 2 :(得分:0)

  1. 您的getter catalogImages()不遵循Java Bean命名约定。我不确定,但它可能会以某种方式混淆JPA提供商。
  2. 使用Collection<CatalogImage>,您已明确告知JPA提供商允许重复。正如已经说过的那样,在大多数情况下使用Set代替Collection解决了重复问题,并且除非您确实需要,否则可以避免FetchType.EAGER