Reputation: 1224
I am trying to group by day / month / year
Expression<String> expression = criteriaBuilder.function(
"to_char", String.class, root.get("reqDate"),
criteriaBuilder.parameter(String.class, "dateSegment"));
query.multiselect(
criteriaBuilder.count(root).alias(FIELD_COUNT), expression.alias("reqDate"))
.groupBy(expression);
entityManager.createQuery(query)
.setParameter("dateSegment","MM-YYYY")
.getResultList();
but this throws an error that the select field must appear in a group by, which already is, I checked the generated sql, it works in db console. but not with JPA, what am i doing it wrong ?
generated sql
select
count(shipment0_.shipment_pk_id) as col_0_0_,
to_char(
shipment0_.requested_delivery_date_time,
?
) as col_2_0_
from
shipment shipment0_
group by
to_char(
shipment0_.requested_delivery_date_time,
?
)
with binding
2019-10-28 09:20:05,891 TRACE [0.0-8080-exec-6 Wcl5M33fEZTS5iF Wcl5M33fEZTS5iF] - o.h.type.descriptor.sql.BasicBinder : binding parameter [6] as [VARCHAR] - [MM-YYYY]
2019-10-28 09:20:05,891 TRACE [0.0-8080-exec-6 Wcl5M33fEZTS5iF Wcl5M33fEZTS5iF] - o.h.type.descriptor.sql.BasicBinder : binding parameter [10] as [VARCHAR] - [MM-YYYY]
why is it binding as two different params?
log
org.postgresql.util.PSQLException: ERROR: column "shipment0_.requested_delivery_date_time" must appear in the GROUP BY clause or be used in an aggregate function
Position: 383
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2183) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:308) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441) ~[postgresql-42.2.5.jar:42.2.5]
Upvotes: 3
Views: 4783
Reputation: 61
Your mistake is that you use criteriaBuilder.parameter(String.class, "dateSegment")
as DateTime formatter. Instead of it you should use cb.literal("MM-YYYY")
and then all should work as expected.
So the correct code is the following:
Expression<String> expression = criteriaBuilder.function(
"to_char", String.class, root.get("reqDate"),
criteriaBuilder.literal("MM-YYYY"));
query.multiselect(
criteriaBuilder.count(root).alias(FIELD_COUNT), expression.alias("reqDate"))
.groupBy(expression);
entityManager.createQuery(query)
.getResultList();
Upvotes: 3
Reputation: 1224
Managed to achieve this by making query look like
select
count(shipment0_.shipment_pk_id) as col_0_0_,
to_char(
shipment0_.requested_delivery_date_time,
?
) as col_2_0_
from
shipment shipment0_
group by
2
Upvotes: 1