我有两个表,这些表之间有一对多的关系。 这是一个表:类别表(父表)
@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
答案 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);
这将从结果集中删除重复项。