2013-04-09 69 views
1

我有两个表:休眠条件加入到表中包含外键

Client (clientId, firstName, lastName, gender) 

Event (clientId, eventId) 

我要代表类似于以下使用条件的查询:

SELECT c.clientId, c.firstName, c.lastName, c.gender, MAX(eventId) 
FROM Client c JOIN Event e ON c.clientId = e.clientId 
GROUP BY c.clientId, c.firstName, c.lastName, c.gender 

我已经试过这样:

final Criteria criteria = session.createCriteria(Client.class); 
criteria.setFetchMode("Event", FetchMode.JOIN); 
criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("clientId")).add(Projections.max("eventId"))); 

但它在带消息的最后一行上引发异常:

HibernateQueryException:无法解析属性:的事件ID: 客户

我怎么可以指定它本身包含的Event没有相关的事件表列,但clientIdClient表之间的连接表是一个外键返回到Client表吗?

正如你所看到的,它真的赶走了Client表,我只需要从Event表中选择最大eventId。另外,正如我所提到的,我正在尝试对基于Client类的现有Criteria查询进行更改。它用于检索所有活动客户端的所有列。我只需要在查询结果中添加一个额外的列 - 最大值为eventId

回答

2

使用别名

Criteria criteria = session.createCriteria(Event.class, "et"). 
createAlias("et.Client", "ct"). 
setProjection(Projections.projectionList().   
add(Projections.groupProperty("et.clientId")). 
add(Projections.max("et.eventId"))); 

有关条件的详细信息,请参阅Criteria Queries

+0

不完全正确。 “客户”类可能不知道“事件”类。 – 2013-04-09 04:15:06

+0

雅正确的感谢。更改了答案 – 2013-04-09 04:26:44

0

这是显而易见的。因为Client类没有eventId属性,并且您的标准被定义为Client类。

当试图在A标准内使用B类的属性时,必须使用别名。

所有你需要做的是修改代码:

final Criteria criteria = session.createCriteria(Event.class, "event"); 
criteria.createAlias("event.client", "client"); 
criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("clientId")).add(Projections.max("eventId"))); 


修订(根据您的评论)

当你的查询需要Event类,你必须这个班有一个Criteria。所以你必须这样:

final Criteria criteria = session.createCriteria(Event.class, "event"); 
criteria.createAlias("event.client", "client"); 
//The criteria below, is returning clientId 
DetachedCriteria eventCr = DetachedCriteria.forClass(Event.class, "event"); 
eventCr.setProjection(Projections.projectionList().add(Projections.groupProperty("clientId")).add(Projections.max("eventId"))); 
//Now using subqueries you can achieve your goal 
criteria.add(Subqueries.propertyIn("clientId", eventCr)); 

我不知道你在找什么,但我希望我给你一些好的提示。如果您的查询必须返回一个ID,您可能需要尝试使用Subqueries.propertyEq

+0

感谢您的回复。 问题是,我正在修改基于客户机类配置的实际基于条件的查询,并实际选择了一些其他客户机列/字段。现在我只需要添加一下,为每个客户端从Event表中检索最大eventId。 有没有办法做到这一点与标准仍然基于客户端类,但加入到事件表中的连接? – 2013-04-09 10:29:27

+0

当然,你可以不用'JOIN'。我建议使用“子查询”。我已经更新了我的答案,以显示如何使用“子查询”。希望对你有帮助。 – 2013-04-09 11:02:18

+0

感谢马丁,但不幸的是我仍然没有得到它:-( – 2013-04-09 20:03:46