Possible bug using CASE WHEN on GROUP BY clause
See original GitHub issueHaving problem when I create a SELECT query with CASE WHEN and use this same CASE on a GROUP BY clause.
My query (listPeople()
method):
public class PersonDAO {
@Inject
private SessionFactory sessionFactory;
public Session getSession() {
return sessionFactory.getCurrentSession();
}
protected JPQLQuery<Person> newQuery() {
return new HibernateQuery<Person>(this.getSession());
}
public List<Tuple> listPeople() {
StringExpression caseExpr = new CaseBuilder() //
.when(person.type.eq("male")).then("M") //
.when(person.status.ne("ACTIVE")).then("I") //
.otherwise("O");
return newQuery() //
.from(QPerson.person) //
.groupBy(caseExpr) //
.select(caseExpr.as("test"), person.count()) //
.fetch();
}
}
My entity/table mapping:
@Entity
@Table(name = "PER_PERSON")
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "PER_ID")
private Long id;
@Column(name = "pes_tp", nullable = false)
private String type;
@Column(name = "pes_st", nullable = false)
private String status;
public Person() {
super();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
The DDL to create the table:
CREATE TABLE per_person
(
PER_ID INTEGER,
pes_tp VARCHAR,
pes_st VARCHAR,
PRIMARY KEY (per_id)
);
The generated SQL seems to be OK, but the database shows an error telling me I have to put PER_PERSON.PES_TP
on the SELECT clause. Here’s the QueryDSL genereted SQL:
SELECT CASE
WHEN person0_.pes_tp = 'male' THEN 'M'
WHEN person0_.pes_st <> 'ACTIVE' THEN 'I'
ELSE 'O'
END AS col_0_0_,
COUNT(person0_.PER_ID) AS col_1_0_
FROM PER_PERSON person0_
GROUP BY CASE
WHEN person0_.pes_tp = 'male' THEN 'M'
WHEN person0_.pes_st <> 'ACTIVE' THEN 'I'
ELSE 'O'
END;
If I run this SQL on the database, it runs successfully. But here’s the stacktrace of the exception thrown:
Hibernate: select case when person0_.pes_tp=? then ? when person0_.pes_st<>? then ? else 'O' end as col_0_0_, count(person0_.PER_ID) as col_1_0_ from PER_PERSON person0_ group by case when person0_.pes_tp=? then ? when person0_.pes_st<>? then ? else 'O' end
2017-08-29 21:09:10 WARN SqlExceptionHelper:144 - SQL Error: 0, SQLState: 42803
2017-08-29 21:09:10 ERROR SqlExceptionHelper:146 - ERROR: column "person0_.pes_tp" must appear in the GROUP BY clause or be used in an aggregate function
Posição: 18
2017-08-29 21:09:10 INFO JdbcCoordinatorImpl:298 - HHH000106: Forcing container resource cleanup on transaction completion
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)
at org.hibernate.loader.Loader.getResultSet(Loader.java:2066)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1863)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839)
at org.hibernate.loader.Loader.doQuery(Loader.java:910)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355)
at org.hibernate.loader.Loader.doList(Loader.java:2554)
at org.hibernate.loader.Loader.doList(Loader.java:2540)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370)
at org.hibernate.loader.Loader.list(Loader.java:2365)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
at com.querydsl.jpa.hibernate.AbstractHibernateQuery.fetch(AbstractHibernateQuery.java:174)
at br.com.dataeasy.chronus.persistencia.hibernate.dao.RelatorioQuadroGeralDAO.listPeople(RelatorioQuadroGeralDAO.java:65)
at br.com.dataeasy.chronus.persistencia.hibernate.dao.RelatorioQuadroGeralDAO.listar(RelatorioQuadroGeralDAO.java:92)
at br.com.dataeasy.chronus.service.RelatorioQuadroGeralService.consultar(RelatorioQuadroGeralService.java:71)
at br.com.dataeasy.chronus.service.RelatorioQuadroGeralService.gerarRelatorio(RelatorioQuadroGeralService.java:83)
at br.com.dataeasy.chronus.service.RelatorioQuadroGeralService$$FastClassBySpringCGLIB$$bdfcdfdb.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at br.com.dataeasy.chronus.service.RelatorioQuadroGeralService$$EnhancerBySpringCGLIB$$a55881d.gerarRelatorio(<generated>)
at WICKET_br.com.dataeasy.chronus.service.RelatorioQuadroGeralService$$FastClassByCGLIB$$bdfcdfdb.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.apache.wicket.proxy.LazyInitProxyFactory$AbstractCGLibInterceptor.intercept(LazyInitProxyFactory.java:350)
at WICKET_br.com.dataeasy.chronus.service.RelatorioQuadroGeralService$$EnhancerByCGLIB$$b30eabd1.gerarRelatorio(<generated>)
at br.com.dataeasy.chronus.web.wicket.pages.relatorio.quadrogeral.RelatorioQuadroGeralPage.doDownloadArquivo(RelatorioQuadroGeralPage.java:77)
at br.com.dataeasy.chronus.web.wicket.components.botoes.BotaoGerarRelatorio$1.getResourceStream(BotaoGerarRelatorio.java:51)
at br.com.dataeasy.chronus.web.wicket.components.link.AjaxDownload.onRequest(AjaxDownload.java:40)
... 79 more
Caused by: org.postgresql.util.PSQLException: ERROR: column "person0_.pes_tp" must appear in the GROUP BY clause or be used in an aggregate function
Posição: 18
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2455)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2155)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:288)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:430)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:356)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:168)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:116)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)
... 115 more
I’m using the following environment:
- Java: 1.8.0_144
- Hibernate: 4.3.10, JPA 2.1
- QueryDSL: 4.0.6 (tried this example on 4.1.0 too)
- DBMS: PostgreSQL 9.6
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource. </bountysource-plugin>
Issue Analytics
- State:
- Created 6 years ago
- Reactions:7
- Comments:6 (1 by maintainers)
Top Results From Across the Web
7 Common GROUP BY Errors - LearnSQL.com
1. Forgetting GROUP BY with Aggregate Functions. You use SELECT statements with the GROUP BY clause when you want to group and organize...
Read more >[Solved] Group by with case statement - CodeProject
Solution 1. Though you have not shared the error, believe the error would be because you have grouped by only brcode and your...
Read more >case statement with group by in jpa named query giving ...
We are getting syntax error in group by clause while using group by with case statement in JPA named queries. We are using...
Read more >Dirty Secrets of the CASE Expression - SQLPerformance.com
Detailed guide with T-SQL CASE expression explanation, examples, and common misconceptions, including WHERE clause and other best practices.
Read more >Case statement possibile BUG - Oracle Communities
You can simplify your test case to comparing a value to results in a subquery expression, having a where clause that could cause...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I don’t know if it’s just a workaround or proper way to do this but it seems to resolve the problem: https://stackoverflow.com/questions/23887678/querydsl-case-expression-with-string-value
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.