在获取数据时休眠重复域

问题描述 投票:0回答:2

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

@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个实体。这是什么原因呢?我该如何克服呢?表数据在这里:“类别表数据”“类别映射表数据”

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

hibernate hibernate-mapping eager-loading
2个回答
1
投票

您已经使toToy协会成为EAGER。这意味着every加载类别时,还将同时获取其所有映射。这意味着,不是检索每个类别一行,而是检索N行。

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

select distinct

而不是

select

但是我不会急于求同。如果在某些用例中确实需要类别及其映射,则显式地获取它们,而不是每次都获取它们,即使在不需要时也是如此:

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

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);

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

© www.soinside.com 2019 - 2024. All rights reserved.