2015-03-02 64 views
2

我想要使用投影获取指定条件的行数。这个想法是计算所有城市所有者的物品。使用条件和投影计算行

实体结构看起来像这样:

@MappedSuperclass 
class BaseEntity implements Serializable { 
    @Expose 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id; 
} 

class Item extends BaseEntity{ 
    @ManyToOne 
    @JoinColumn(name = 'owner_id') 
    Owner owner; 
} 

class Owner extends BaseExntity{ 
    @ManyToOne 
    @JoinColumn(name = "city_id") 
    City city; 
} 

class City extends BaseExntity{ 
    @Column(name = "name") 
    String name; 
} 

要选择数据I使用的下一个代码与休眠标准:

Criteria c = session.createCriteria(Item.class); 

//just select all instances that have cityId = 1 
c.createAlias("owner.city", "city"); 
c.add(Restrictions.like("city.id", 1L)); 
c.list(); //1st invocation, this works well 

//Trying to count instances that have cityId = 1 
ProjectionList properties = Projections.projectionList(); 
properties.add(Projections.rowCount(), "count"); 

c.setProjection(properties); 
c.list(); //2nd invocation, here I receive an exception - object not found: CITY1_.ID 

在第二c.list()调用SQL查询看起来像: 休眠:从项目this_中选择count(*)作为y0_,其中city1_.id就像?

而且现在还不清楚,我为什么第一c.list()调用的效果很好,但是当我试图用计数凸起列它不工作,并抛出未发现对象:CITY1_.ID

Hibernate的版本是4.3.4.Final

+0

如果您只调用一次'c.list();'会发生什么? – JamesENL 2015-03-03 01:40:09

+0

如果我删除了第一次调用c.list(),它会失败,并显示相同的错误 - 未找到对象:CITY1_.ID – igor 2015-03-03 06:05:12

+0

我认为您必须使用Projections.alias方法将该别名添加到投影中。 – JamesENL 2015-03-03 06:13:21

回答

1

解决: 看起来像Hibernate不支持与预测的多个关联的别名,但对于标准一样。因此,我改变了标准的别名来源:

Criteria c = session.createCriteria(Item.class); 
c.createAlias("owner.city", "city"); 
c.add(Restrictions.like("city.id", 1L)); 

到:

Criteria c = session.createCriteria(Item.class, "i"); 
c.createAlias("i.owner", "owner"); 
c.createAlias("owner.city", "city"); 
c.add(Restrictions.eq("city.id", 1L)); 

现在投影计数效果很好。