【问题标题】:Hibernate criteria with projection doesn't return the entity on which criteria is implemented带有投影的休眠标准不返回实施标准的实体
【发布时间】:2011-11-27 10:37:28
【问题描述】:

我正在使用 spring-hibernate 并使用 HibernateDAOSupport 类。 我有两张表以一对多的方式相互映射。 我正在执行以下标准

 DetachedCriteria criteria = getCriteria( "a" )
        .setProjection( Projections.projectionList()
                .add( Projections.groupProperty("a.id" ) )
                .add( Projections.count( "a.id" ), "count" )
                )
        .createCriteria( "huApps", "hu")
        .addOrder( Order.desc( "count" ) )
        ;

这很好用并创建以下查询

select
        this_.id as y0_,
        count(this_.id) as y1_ 
    from
        apps this_ 
    inner join
        huapps huapp1_ 
            on this_.id=huapp1_.appid 
    group by
        this_.id 
    order by
        y1_ desc

结果,它返回object[] 的列表。但我希望它应该返回List<App>(App 是我实现/创建标准的类)。 我希望它会创建查询

select
 this_
    from
        apps this_ 
    inner join
        huapps huapp1_ 
            on this_.id=huapp1_.appid 
    group by
        this_.id 
    order by
        y1_ desc

请帮我写出正确的标准。 我也试过sqlProjection(),但即使这样也没有用。 有什么办法可以实现吗?

【问题讨论】:

    标签: hibernate spring criteria


    【解决方案1】:

    尝试调用

    DetachedCriteria criteria = getCriteria( "a" )
        .setProjection( Projections.projectionList()
        .add( Projections.groupProperty("a.id" ), "id" )
                .add( Projections.count( "a.id" ), "count" )
                )
        .createCriteria( "huApps", "hu")
        .addOrder( Order.desc( "count" ) )
        .setResultTransformer(Transformers.aliasToBean(App.class))
    

    这应该将属性别名映射到您指定的 bean 的字段。应用将需要相应字段的 setter 和 getter

    【讨论】:

      【解决方案2】:

      您尝试为函数detachedCriteria.createCriteria("huApps", "hu") 的结果添加新标准。此函数返回 huApp 属性类的新标准。

      尝试像这样替换您的标准:

      DetachedCriteria detachedCriteria = DetachedCriteria.forClass(A.class);
      detachedCriteria.setProjection(Projections.projectionList()
                  .add(Projections.groupProperty("id"))
                  .add(Projections.count("id"), "count")
          );
      
      detachedCriteria.createCriteria("huApps", "hu");
      detachedCriteria.addOrder(Order.desc("count"));
      
      List<A> list = detachedCriteria.getExecutableCriteria(getSession()).list();
      

      它对我很有效。

      【讨论】:

      • 再次创建相同的查询 select this_.id as y0_, count(this_.id) as y1_ from ChleonCloudVault.apps this_ inner join ChleonCloudVault.huapps huapp1_ on this_.id=huapp1_.appid group by this_ .id 按 y1_ desc 排序
      • 这个sql是怎么生成的?这串代码detachedCriteria.getExecutableCriteria(getSession()).list()返回List类的实例,但我指定了所需类型的泛型
      • 是的,它返回一个 List。列表的每个元素都包含一个 Object 数组(每个元素的大小为 2)。在 index=0、id 和 index=1 处,该应用程序的计数。并且提供的sql是由Hibernate生成的。
      • 哦!也许我应该戴眼镜。我很抱歉我的疏忽。但是你不能在 sql 中提供你想要的请求。 Sql 只能获取您分组的字段或一些聚合函数,如 max 或 count。所以你得到的结果不是休眠限制。您在 sql 中所需的请求如下所示:SELECT a.* FROM A_TABLE a INNER JOIN (SELECT field, count(*) as score from A_TABLE GROUP BY field) b ON a.field = b.field ORDER BY b.score 所以您必须使用子查询进行内部选择。
      猜你喜欢
      • 2011-04-11
      • 2015-07-17
      • 1970-01-01
      • 1970-01-01
      • 2017-05-25
      • 2012-09-06
      • 1970-01-01
      • 2015-05-09
      • 2017-12-11
      相关资源
      最近更新 更多