postgresql - JPA2 Criteria API 在使用 groupBy 时创建无效的 SQL

标签 postgresql jpa-2.0 criteria-api

带有 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);

也会导致同样的错误。

有人知道如何解决这个问题吗?

最佳答案

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

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

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

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

关于postgresql - JPA2 Criteria API 在使用 groupBy 时创建无效的 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12403399/

相关文章:

java - JPA 标准多对多加入还是不加入?

c# - 如何将输入数据发送到 Postgres psql.exe?

sql - 如何 UNNEST、GROUP 和 JOIN 数组?

postgresql - 子查询结果中的模式匹配

JPA 2.0、Criteria API、子查询、表达式

java - Spring data JPA中findBy和findOneBy的区别

java - JPA与eclipse链接结果列表迭代到无穷大

SQL 克隆和转换日期列

java - Criteria API - 具有参数表达式的优点

JPA 表达式连接多于两列