PostgreSQL 查询在 pgAdmin 中有效,但在 Java EclipseLink 中无效

PostgreSQL query works in pgAdmin but not in Java EclipseLink

我有一个 SQL 计算每个截断日期(月、日、小时)的行数。想想历史图表。如果在 pgAdmin 中执行,查询工作正常,但在 Java 中使用 EclipseLink 失败。

pgAdmin 查询:

SELECT date_trunc( 'hour', delivered_at ),
       COUNT(date_trunc( 'hour', delivered_at )) AS num 
FROM messages 
WHERE channel_type='EMAIL' 
  AND created_at>='2016-02-28 16:01:08.882' 
  AND created_at<='2016-02-29 16:01:08.882' 
GROUP BY date_trunc( 'hour', delivered_at );

JPQL 命名查询

SELECT FUNCTION('date_trunc', 'hour', m.deliveredAt ),
       COUNT(FUNCTION('date_trunc', 'hour', m.deliveredAt )) AS num 
 FROM Message m 
 WHERE m.channelType = :channelType 
   AND m.createdAt >= :fromDate 
   AND m.createdAt <= :toDate 
 GROUP BY FUNCTION('date_trunc', 'hour', m.deliveredAt )

EclipseLink 调试日志:

SELECT date_trunc(?, delivered_at), COUNT(date_trunc(?, delivered_at)) FROM messages 
WHERE (((channel_type = ?) AND (created_at >= ?)) AND (created_at <= ?)) GROUP BY date_trunc(?, delivered_at)
bind => [hour, hour, EMAIL, 2015-12-27 00:00:00.0, 2015-12-27 00:00:00.0, hour]

错误:

ERROR: column "messages.delivered_at" must appear in the GROUP BY clause or be used in an aggregate function Position: 23

PostgreSQL 日志:

2016-03-01 13:22:08 CET ERROR: column "messages.delivered_at" must appear in the GROUP BY clause or be used in an aggregate function at character 23 2016-03-01 13:22:08 CET STATEMENT: SELECT date_trunc(, delivered_at), COUNT(delivered_at) FROM messages WHERE (((channel_type = ) AND (created_at >= )) AND (created_at <= )) GROUP BY date_trunc(, delivered_at) 2016-03-01 13:22:08 CET LOG: execute S_2: SELECT 1

如果我从 EclipseLink 记录的查询中替换绑定变量并在 pgAdmin 中执行它,则查询有效。这是怎么回事?

编辑:澄清一下,它也适用于 em.createNativeQuery。

在 postgresql 上,您可以使用以下语法

GROUP BY 1

这意味着您将使用 SELECT 子句中第一个选定的属性对聚合进行分组。这可能对您有帮助

PostgreSQL 可以有 trouble 解析参数绑定,在这种情况下表现为本机 SQL 参数内联工作,而 JPA 生成 SQL 默认值绑定参数失败。

一个解决方案是关闭参数绑定,方法是将 "eclipselink.jdbc.bind-parameters" 的值 "false" 作为特定查询的查询提示,或作为持久性单元 属性 传递给默认关闭所有查询的参数绑定。