hibernate criteria group by sub-property

时间:2013-01-07 09:26:13

标签: hibernate hibernate-criteria

假设如下:

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
}

我想使用企业的hibernate条件分组结果执行查询。

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

执行此hibernate时返回exeption:org.hibernate.QueryException:无法解析属性:site.enterprise ...

有一些优雅的方法如何做到这一点。提前谢谢。

1 个答案:

答案 0 :(得分:7)

我可能需要首先设置别名:

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

我甚至不确定你为什么要将它分组......