question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Possible bug using CASE WHEN on GROUP BY clause

See original GitHub issue

Having 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
<bountysource-plugin>

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource. </bountysource-plugin>

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:7
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
orzechocommented, Oct 9, 2018

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

0reactions
stale[bot]commented, Jul 23, 2022

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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found