【问题标题】:How to add Distinct in Hibernate Criteria如何在 Hibernate Criteria 中添加 Distinct
【发布时间】:2012-05-24 05:39:10
【问题描述】:

在我的数据库中,我有一个 Test 表,其中包含以下列:testName、testType 有 2 个不同的测试具有相同的类型,即“SUN”,所以我只想要其中一个在我的休眠/标准中使用 Distinct,如下所示,但它仍然给了我与“sun”同名的两种类型.

        Criteria crit = session.createCriteria(Test.class);

    final ResultTransformer trans = new DistinctRootEntityResultTransformer();
    crit.setResultTransformer(trans);
    List rsList = trans.transformList(crit.list());

知道可能是什么原因,或任何其他过滤重复项的方式。

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    使用 Projections.distinct。

    Criteria crit = session.createCriteria(Test.class).setProjection(
        Projections.distinct(Projections.projectionList()
        .add(Projections.property("type"), "type") )
    .setResultTransformer(Transformers.aliasToBean(YourBean.class)); 
    
    List lst = crit.list();
    

    YourBean.class 有一个属性“类型”。返回的列表将为List<YourBean>

    【讨论】:

    • 谢谢,现在它给出了正确的结果,但是它在这个语句之后是一个字符串的形式,而我想要完整的对象并返回完整的对象,我也想要 testname 值,如何我能得到那个
    • @Dandy,提供了很好的答案,但我仍然遇到问题。我得到的 bean 只包含“类型”。 Test 类的其他属性具有 null 或 0 值。如何获取这些值以及唯一类型限制。
    • 是不是少了一个括号?
    • 对我来说返回的是List<typeOf"type"Field>
    【解决方案2】:

    尝试使用:

    cr.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    

    它对我来说非常有用

    【讨论】:

    • 你能补充更多关于它为什么对你有用的信息吗?
    • 很好的答案,也适用于我的案例,仅额外增加 1 行(而不是 10...)
    • 这是非常有限的解决方案。使用ResultTransformer时,hibernate在SQL查询中不包含DISTINCT,所以我们遇到了分页(limit/offset)的麻烦
    • 就我而言,当我需要在外部连接中获取详细信息时,它可以完美运行。休眠,否则为每个细节乘以结果集中的 identical 对象。为了减少那些意想不到的重复,它工作得很好。当然,对于分页来说,这种方法是没有用的。
    • Muhammad Abdul-Rahim,这个 Distinct 不是在数据库选择级别上完成的 - 没有 distinct 时相同,而是在内存中对象结果集的获取和形成集合的级别上。简单地说,相同的乘法对象(实际上是相同的 - 有 objectid1 == objectid2...)被缩小为一个。
    【解决方案3】:

    我终于发现可以获取其他列的值了:

    Criteria criteria = session.createCriteria(Test.class);
    ProjectionList projectionList = Projections.projectionList();
    ProjectionList projectionList2 = Projections.projectionList();
    projectionList2.add(Projections.distinct(projectionList.add(Projections.property("distinctColumn"), "distinctColumn")));
    projectionList2.add(Projections.property("col1"), "col1");
    projectionList2.add(Projections.property("col2"), "col2");
    criteria.setProjection(projectionList2);
    criteria.setResultTransformer(Transformers.aliasToBean(Test.class)); 
    List list = criteria.list();
    

    【讨论】:

      【解决方案4】:

      尝试使用:

      Criteria criteria = 
          session.createCriteria(Test.class).setProjection(
              Projections.distinct(Projections.property("testType")));
      List<Test> rsList = criteria.list();
      

      【讨论】:

        【解决方案5】:

        遇到了同样的问题,最终使用 Group By 投影解决了问题,然后添加了我需要的所有列。例如

        Criteria query = session.createCriteria(Class.class)
            .setProjection(Projections.projectionList()
                .add(Projections.groupProperty("Col1"), "Col1")
                .add(Projections.groupProperty("Col2"), "Col2"))
            .setResultTransformer(Transformers.aliasToBean(Class.class));
        List list =  query.list();
        

        【讨论】:

          【解决方案6】:

          试试

          setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

          Criteria crit = session.createCriteria(Test.class);

          List list = crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();

          【讨论】:

            【解决方案7】:

            投影仅提供标记属性的结果。但是,它给子实体带来了问题。请参阅我的帖子了解我遇到的真正问题。

            Hibernate: Parent and Child relationship data structure

            【讨论】:

              【解决方案8】:

              尝试使用:

              criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);
              

              它使用默认哈希码在结果中查找匹配项。

              谢谢。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-02-24
                • 2012-09-07
                • 2018-03-02
                相关资源
                最近更新 更多