在获取数据时休眠重复的domians

时间:2014-02-04 07:48:41

标签: hibernate hibernate-mapping eager-loading

我有两个表,这些表之间有一对多的关系。    这是一个表:类别表(父表)

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@Column(name="CATEGORY_NAME")
private String categoryName;

//bi-directional many-to-one association to TmCategoryPropertiesMapping
@OneToMany(mappedBy="tmCategory", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<TmCategoryPropertiesMapping> tmCategoryPropertiesMappings;
.............
....... getter and setters

和另一个实体:类别映射表(子表)

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@Column(name="CREATED_BY")
private BigInteger createdBy;

@Column(name="CREATED_DATE")
private Timestamp createdDate;

@Column(name="PROPERTY_ID")
private BigInteger propertyId;

//bi-directional many-to-one association to TmCategory
@ManyToOne
@JoinColumn(name="CATEGORY_ID")
private TmCategory tmCategory;

如果我使用所有者ID获取类别,我会在结果中获得重复项。 即使我在类别表中只有3个条目,但我的结果中有10个实体。 任何人都能告诉我这是什么原因。 我怎么能从这里过来? 表格数据如下: category table data category mapping table data

我得到的结果是 id = 1,1,2,2,2,3,3,3,3

2 个答案:

答案 0 :(得分:1)

您已将toMany协会设为EAGER。这意味着每个时间加载一个类别,其所有映射也都会被识别。这意味着,不是每个类别检索一行,而是检索N行。

要对结果列表进行重复数据删除,只需

即可
select distinct

而不是

select

但我不会让toMany协会渴望。如果你确实需要在某些用例中使用其映射的类别,则明确地获取它们,而不是每次都获取它们,即使在不需要时也是如此:

select distinct c from Category c
left join fetch c.tmCategoryPropertiesMappings
where ...

答案 1 :(得分:0)

好的,我明白了。 与具有急切提取的表的关系会发生这种情况。 为了摆脱这个问题,我们需要在标准本身中指定不同的,这是解决方案:

DetachedCriteria criteria = DetachedCriteria.forClass(Category.class);
        criteria.add(Restrictions.eq("ownerId", BigInteger.valueOf(id)));
    criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        List<Category> categories = getHibernateTemplate().findByCriteria(criteria);

注意这一行

            criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

这将从结果集中删除重复项。