【问题标题】:How to prevent duplicate results in Hibernate?如何防止 Hibernate 中的重复结果?
【发布时间】:2014-03-27 14:20:50
【问题描述】:

当尝试搜索关系的多个值时,会返回重复的结果。

如何避免这些重复?

我们的服务上有一个构建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 个带有 &lt;id 1&gt; 和 1 个带有 &lt;id 2&gt;

我想将结果列表放在Set 中以消除重复,但随后分页不再正确。

我该怎么办?

【问题讨论】:

    标签: java hibernate criteria hibernate-criteria


    【解决方案1】:

    尝试添加setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 以删除重复条目,并添加setProjection(Projections.distinct(Projections.property("id"))) 以在创建条件对象时获取正确的行数。

    【讨论】:

    • 不起作用:删除重复项但计数仍然错误。
    • 仍然不起作用:createCriteria(values).setProjection(Projections.distinct(Projections.property("id"))).setProjection(Projections.rowCount()).uniqueResult(); 返回 3。
    【解决方案2】:

    尝试使用这个投影:

    .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。

    【讨论】:

      【解决方案3】:

      我知道这是一个旧线程,但在某些情况下,如果有人仍然遇到这个问题,这对我有用。更多详情here

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

      【讨论】:

        猜你喜欢
        • 2018-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-16
        • 2014-08-02
        相关资源
        最近更新 更多