在获取数据时休眠重复域

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在获取数据时休眠重复域相关的知识,希望对你有一定的参考价值。

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

@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

答案

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

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

select distinct

而不是

select

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

select distinct c from Category c
left join fetch c.tmCategoryPropertiesMappings
where ...
另一答案

好吧,我明白了。这与渴望获取表的关系有关。为了解决这个问题,我们需要在标准中指定不同的标准,这是解决方案:

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

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

以上是关于在获取数据时休眠重复域的主要内容,如果未能解决你的问题,请参考以下文章

在选择期间休眠重复的行

从外部api获取数据时反应应用程序中的Cors错误[重复]

在 AsyncUncaughtExceptionHandler 中获取休眠会话

休眠:获取太多行

Android App无法从Web获取数据[重复]

使用休眠从数据库中获取下一个序列值