我可以在hibernate中使用Projections通过嵌套关联实体进行分组吗?

时间:2010-11-30 02:29:26

标签: hibernate group-by

如果我有类似的实体:

@Entity
public class Person {
   public String name;
   @OneToMany
   public Location location;
}

@Entity
public class Location {
   public String address;
   public String city;
   public String state;
}

说我想计算每个州的所有人。我能不能做这样的事情:

Criteria criteria = session.createCriteria(Person.class);
criteria.setProjection(Projections.projectionList().
   add(Projections.groupProperty("location.state")).
   add(Projections.count("name")));
List<Object[]> result = criteria.list();

我知道确切的示例不起作用,因为我收到错误说could not resolve property: location.state of of: Person。有没有办法在不诉诸HQL的情况下做我想做的事情? (此查询的真实版本非常动态,因此标准的编程构建非常有用。)

2 个答案:

答案 0 :(得分:0)

您可以将位置设置为Person的关联,然后将其分组。例如:

session.createCriteria(Person.class)
         .add(Projections.count("name"))
       .createCriteria(Location.class)
         .add(Projections.groupProperty("state"))

未经测试,但应该有效:-)

答案 1 :(得分:0)

首先,我在上面创建了一个玩具示例,因此玩具可能会起作用,甚至部分建议也可能适用于玩具示例。文档似乎表明要么应该,但它在我的真实场景中不起作用,这个场景太冗长了。

问题是找不到location.state属性。最终工作的是明确地在标准中创建别名:

criteria.createAlias("location", "location").createAlias("location.state", "state");

我仍然无法使用“状态”别名,但“location.state”随后为我工作,因此创建别名以某种方式启动了查询构建器,以便能够在之前无法找到它。这一切看起来都非常粗俗和不优雅,所以我并不为这个解决方案感到自豪,但这才是最有效的。这听起来像是其他人的错误吗?

对于那些好奇的人,没有进入整个实体模型,这里有适合我的实际标准和预测:

obsCriteria.createAlias("phenomenon", "phenomenon").createAlias(
  "phenomenon.phenomenonGroup", "phenomenonGroup");
ProjectionList projection = Projections.projectionList()
  .add(Projections.avg("value"))
  .add(Projections.groupProperty("phenomenon.phenomenonGroup"));
obsCriteria.setProjection(projection);