我有两个表:
Client (clientId, firstName, lastName, gender)
Event (clientId, eventId)
我需要用Criteria表示一个类似于下面的查询:
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:无法解析property: eventId of:客户
我如何指定Client
表之间的连接,它本身不包含与事件表相关的列,但Event
表上的clientId
列是回Client
表的外键?
正如您所看到的,它实际上已经从Client
表中移除,我只需要从Event
表中选择最大的eventId
。此外,正如我提到的,我正试图对基于Client
类的现有Criteria查询进行更改。它用于检索所有活动客户机的所有列。我只需要在查询结果中添加一个额外的列-最大eventId
。
使用别名
Criteria criteria = session.createCriteria(Event.class, "et").
createAlias("et.Client", "ct").
setProjection(Projections.projectionList().
add(Projections.groupProperty("et.clientId")).
add(Projections.max("et.eventId")));
有关标准的更多详细信息,请参阅标准查询
这很明显。因为Client
类没有eventId
属性,而你的标准是为Client
类定义的。
当试图在a的Criteria中使用B类的属性时,必须使用Aliases
你所要做的就是像这样修改你的代码: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
。