Hibernate Criteria连接到包含外键的表

时间:2013-04-09 03:59:36

标签: java sql hibernate hibernate-criteria

我有两张桌子:

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:无法解析属性:eventId:   客户端

如何指定Client表之间的连接,该表本身不包含与Event表相关的列,但clientId表上的Event列是一个返回到Client表?

正如您所看到的,它实际上是从Client表驱动的,我只需要从eventId表中选择最大Event。另外,正如我所提到的,我正在尝试更改基于Client类的现有Criteria查询。它用于检索所有活动客户端的所有列。我只需要在查询结果中添加一个额外的列 - 最大eventId

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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