3

假设如下:

public class Enterprise
{
   private int id;
   private String name;
}
public class Site
{
   private int id;
   private String name;
   private Enterprise enterprise; //@ManyToOne relation
}
public class Area
{
   private int id;
   private String name;
   private Site site; //@ManyToOne relation
}

我想按企业使用休眠标准分组结果执行查询。

    Criteria criteria = session.createCriteria(Area.class);
    criteria.setProjection(Projections.projectionList()  
                    .add(Property.forName("id").as("id")) 
                    .add(Property.forName("name").as("name"))
        .add(Projections.groupProperty("site.enterprise")))
        .setResultTransformer(Transformers.aliasToBean(Area.class));
/*
 * more conditions
 */
    List<Area> areas = criteria.list();

执行此休眠时返回异常:org.hibernate.QueryException:无法解析属性:site.enterprise ...

有没有一些优雅的方法来做到这一点。先感谢您。

4

1 回答 1

9

我相信您可能需要先设置别名:

criteria.createAlias("site", "s")

然后使用:

Projections.groupProperty("s.enterprise")

您可能还需要对字段而不是实体进行分组,因此:

site.enterprise.name // or id

这可能需要您也为其创建别名,enterprise但您可能不需要。

更新1:你可能会得到这样的结果:

Criteria criteria = session.createCriteria(Area.class);
criteria.createAlias("site", "s")
        .createAlias("s.enterprise", "e")
        .setProjection(Projections.projectionList()  
                .add(Property.forName("id").as("id")) 
                .add(Property.forName("name").as("name"))
    .add(Projections.groupProperty("s.e.name")))
    .setResultTransformer(Transformers.aliasToBean(Area.class));

更新 2:叫我疯了,但从上面的例子来看,你可能会采取一种非常冗长的方法,没有充分利用 Hibernate 的潜力——看起来你正试图像使用 SQL 一样使用它。Hibernate 已经知道您的实体、它们的字段和关系。在我看来,这相当于上面的:

Criteria criteria = session.createCriteria(Area.class);
criteria.createAlias("site", "s")
        .createAlias("s.enterprise", "e")
        .add(Projections.groupProperty("s.e.name"));

// Any other conditions.

List<Area> areas = criteria.list();

我什至不确定你现在为什么要分组...

于 2013-01-07T09:39:59.377 回答