2

带有 Criteria API 的 JPA2 似乎为 PostgreSQL 生成了无效的 SQL。对于此代码:

Root<DBObjectAccessCounter> from = query.from(DBObjectAccessCounter.class);
Path<DBObject> object = from.get(DBObjectAccessCounter_.object);
Expression<Long> sum = builder.sumAsLong(from.get(DBObjectAccessCounter_.count));
query.multiselect(object, sum).groupBy(object);

我得到以下异常:

ERROR: column "dbobject1_.id" must appear in the GROUP BY
clause or be used in an aggregate function

生成的 SQL 为:

select dbobjectac0_.object_id as col_0_0_,
    sum(dbobjectac0_.count) as col_1_0_, dbobject1_.id as id1001_,
    dbobject1_.name as name1013_,
    dbobject1_.lastChanged as lastChan2_1013_,
    dbobject1_.type_id as type3_1013_
    from DBObjectAccessCounter dbobjectac0_
    inner join DBObject dbobject1_
    on dbobjectac0_.object_id=dbobject1_.id
    group by dbobjectac0_.object_id

显然,select 语句的第一项(dbobjectac0_.object_id)与group by 子句不匹配。

简化示例

它甚至不适用于这个简单的示例:

Root<DBObjectAccessCounter> from = query.from(DBObjectAccessCounter.class);
Path<DBObject> object = from.get(DBObjectAccessCounter_.object);
query.select(object).groupBy(object);

返回

select dbobject1_.id as id924_, dbobject1_.name as name933_,
    dbobject1_.lastChanged as lastChan2_933_,
    dbobject1_.type_id as type3_933_
    from DBObjectAccessCounter dbobjectac0_
    inner join DBObject dbobject1_
    on dbobjectac0_.object_id=dbobject1_.id
    group by dbobjectac0_.object_id

并产生与上述相同的错误。

按 ID 而非类型分组

按照错误消息的建议按 ID 分组

Root<DBObjectAccessCounter> from = query.from(DBObjectAccessCounter.class);
Path<DBObject> object = from.get(DBObjectAccessCounter_.object);
Path<Long> objectId = from.get(DBObjectAccessCounter_.object).get(DBObject_.id);
query.select(object).groupBy(objectId);

也会导致同样的错误。

有谁知道如何解决这一问题?

4

2 回答 2

1

PostgreSQL 9.2 及更高版本在检测“隐式分组”列的方式上有所改进,即您将主键放入的位置,group by因此该表中的所有字段都可以在 SELECT 列表中引用。以前的版本没有检测到这一点,因此SELECT id, somefield FROM sometable GROUP BY id会导致Column sometable.somefield must appear in the GROUP BY clause. 在较新的版本中,Pg 将检测到somefield隐式分组,因为它id被包含并允许此查询运行。

不幸的是,我不确定这是否能解决您的问题;您的问题是您正在按联接条件另一侧的键进行分组,我怀疑 Pg 会将其识别为 PK,因为该列未标记为这样。

我建议您编写一个独立的测试用例并在 Hibernate JIRA 上提交问题报告。链接到这里;一旦有一个完整且可运行的测试用例,我就会试一试。

此外,您确定错误消息在您更改的测试用例中保持完全相同,它没有引用不同编号的别名或任何东西吗?

于 2012-09-16T00:11:46.650 回答
0

我已经在EclipseLinkand上测试了你的第一个例子MySql。它不会引发任何异常,如果我没有误解您的目标,那么结果查询就是您要查找的内容:

SELECT t0.id, t0.name, SUM(t1.count) 
FROM dbobject t0, dbobjectaccesscounter t1 
WHERE (t0.id = t1.object_id) GROUP BY t0.id, t0.name
于 2012-09-14T19:10:02.480 回答