尝试搜索关系的多个值时,将返回重复的结果。
如何避免这些重复?
我们的服务有一种方法可以构建Criteria
:
@Override
protected Criteria createCriteria(Map<String, Object> values) {
Criteria criteria = super.createCriteria(values);
if (criteria != null && values != null) {
// other criteria restrictions
Set<MDTErkenning> erkenningen = (Set<MDTErkenning>) values.get("erkenningen");
if (erkenningen != null && !erkenningen.isEmpty()) {
criteria.createAlias("erkenningen", "erkenningen");
criteria.add(Restrictions.in("erkenningen." + CollectionPropertyNames.COLLECTION_ELEMENTS, erkenningen));
}
}
return criteria;
}
用于获取分页结果并进行计数:
@Override
public List<T> findByCriteria(Map<String, Object> values, int offset, int amount) {
Criteria criteria = createCriteria(values)
.setFirstResult(offset)
.setMaxResults(amount);
return criteria.list();
}
@Override
public Long getCount(Map<String, Object> values) {
Criteria criteria = createCriteria(values).setProjection(Projections.rowCount());
return (Long) criteria.uniqueResult();
}
主体
@Entity
@Table(name = "mdt")
public class MultiDisciplinairTeam {
@Id
@Column(name = "mdt_uuid")
private String id;
// other mappings
@Column(name = "erkenning")
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@ElementCollection(fetch = FetchType.EAGER)
@Enumerated(EnumType.STRING)
@JoinTable(name = "mdt_erkenning", joinColumns = {@JoinColumn(name = PK_NAME)})
@Fetch(FetchMode.SELECT)
private Set<MDTErkenning> erkenningen;
// getters & setters
}
枚举而不是实体
public enum MDTErkenning {
ZORG("Zorg"),
IMB("IMB"),
PAB("PAB"),
ROLSTOELEN("Rolstoelen");
private String beschrijving;
private MDTErkenning(String beschrijving) {
this.beschrijving = beschrijving;
}
public String getBeschrijving() {
return this.beschrijving;
}
}
连接表mdt_erkenning
包含一些数据:
------------------------
| mdt_uuid | erkenning |
------------------------
| <id 1> | ZORG |
| <id 1> | PAB |
| <id 2> | ZORG |
| <id 2> | IMB |
------------------------
所以如果我查询例如。ZORG 和 PAB 我得到了我的实体的 3 个实例:2 个带有 <id 1>
个实例,1 个带有 <id 2>
个实例。
我想将结果列表放在一个Set
中以消除重复项,但随后分页不再正确。
我该怎么办?
尝试添加用于删除重复条目的setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
,并在创建条件对象时添加用于获取正确行计数setProjection(Projections.distinct(Projections.property("id")))
。
尝试使用此投影:
.setProjection(Projections.countDistinct("id"))
对于您的示例:
@Override
public Long getCount(Map<String, Object> values) {
Criteria criteria = createCriteria(values).setProjection(Projections.countDistinct("id"));
return (Long) criteria.uniqueResult();
}
我正在使用Hibernate 4.3.6.Final。
这是一个旧线程,但万一,如果有人仍然遇到这个问题,这对我有用。更多细节在这里
public List<User> getUserByUsername (String username)
{
Session session = sessionFactory.getCurrentSession();
return session.createCriteria(User.class)
.add(Restrictions.eq("username", username))
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list();
}