Dears,
I believe to have found a bug in the HQL query translation code. When I attempt to execute the following HQL query:
Code:
select c
from Company as c inner join c.products as p
where c.enabled = true
group by c
having count(p) > 0
order by count(p) desc
the translator yields a sql query like the following:
Code:
select c.id, c.ragSoc, c.idLogo, c.enabled, c.eMail, c.address1, c.address2, c.zip, c.city, c.state, c.idCountry, c.phone, c.fax, c.vat, c.site
from comp.companies c inner join prod.companyProducts p on c.id=p.idCompany
where c.enabled=true
group by c.id
having count((p.idProduct, p.idCompany))>0
order by count((p.idProduct, p.idCompany)) desc
which is basically wrong to my postgresql 8.0. It should be:
Code:
select c.id, c.ragSoc, c.idLogo, c.enabled, c.eMail, c.address1, c.address2, c.zip, c.city, c.state, c.idCountry, c.phone, c.fax, c.vat, c.site
from comp.companies c inner join prod.companyProducts p on c.id=p.idCompany
where c.enabled=true
group by c.id, c.ragSoc, c.idLogo, c.enabled, c.eMail, c.address1, c.address2, c.zip, c.city, c.state, c.idCountry, c.phone, c.fax, c.vat, c.site
having count((p.idProduct, p.idCompany))>0
order by count((p.idProduct, p.idCompany)) desc
Is there any way to circumvent the problem? I would like to retrieve all the companies having products, ordered by descreasing number of offered products. Please note that using a sorted set wouldn't work: there are 2k products and dereferencing c.products would start a slow (and useless) loading of the product's details...
Oh, also note that, as long as I'm using a "inner join", the "having" construct is useless. I left this because this way the query is much more close to the one reported @ page 150 of the hibernate_reference.pdf v. 3.1.3:
Code:
select cat
from Cat cat
join cat.kittens kitten
group by cat
having avg(kitten.weight) > 100
order by count(kitten) asc, sum(kitten.weight) desc
Cheers,
giampaolo
Hibernate version: 3.2 cr2 (same problem with 3.0.5, too)
Mapping documents: Code:
<class name="it.mycomp.myapp.persistence.company.Company"
schema="comp" table="companies"
>
<id name="id"><generator class="native"><param name="sequence">comp.companies_id_seq</param></generator></id>
<property name="ragSoc"
type="java.lang.String"
length="32"
not-null="true"
unique="true"
/>
<many-to-one name="logo"
class="it.mycomp.myapp.persistence.image.Image"
column="idLogo"
/>
<property name="enabled"
type="boolean"
not-null="true"
/>
<property name="eMail"
type="java.lang.String"
length="64"
not-null="true"
/>
<component name="postalAddress"
class="it.mycomp.myapp.persistence.person.PostalAddress"
>
<property name="address1"
type="java.lang.String"
length="64"
not-null="true"
/>
<property name="address2"
type="java.lang.String"
length="64"
/>
<property name="zip"
type="java.lang.String"
length="8"
/>
<property name="city"
type="java.lang.String"
length="32"
/>
<property name="state"
type="java.lang.String"
length="32"
/>
<many-to-one name="country"
class="it.mycomp.myapp.persistence.tables.Country"
column="idCountry"
not-null="true"
/>
</component>
<property name="phone"
type="java.lang.String"
length="32"
/>
<property name="fax"
type="java.lang.String"
length="32"
/>
<property name="vat"
type="java.lang.String"
length="16"
/>
<property name="site"
type="text"
not-null="true"
/>
<set name="users"
inverse="true"
lazy="true"
>
<key column="idCompany" />
<one-to-many class="it.mycomp.myapp.persistence.company.CompanyUser" />
</set>
<set name="products"
inverse="true"
lazy="true"
>
<key column="idCompany" />
<one-to-many class="it.mycomp.myapp.persistence.product.CompanyProduct" />
</set>
</class>
<class name="it.mycomp.myapp.persistence.product.CompanyProduct"
schema="prod" table="companyProducts"
>
<composite-id name="primaryKey"
class="it.mycomp.myapp.persistence.product.CompanyProductPK"
access="property"
>
<key-many-to-one name="product"
column="idProduct"
class="it.mycomp.myapp.persistence.product.Product"
/>
<key-many-to-one name="company"
column="idCompany"
class="it.mycomp.myapp.persistence.company.Company"
/>
</composite-id>
<property name="availableQty"
not-null="false"
/>
<property name="minOrderQty"
not-null="true"
/>
<property name="stepOrderQty"
not-null="true"
/>
<property name="unitPrice"
not-null="true"
/>
</class>
Full stack trace of any exception that occurs:Code:
15:36:05,968 ERROR [STDERR] org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.doList(Loader.java:2148)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2029)
at org.hibernate.loader.Loader.list(Loader.java:2024)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:392)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:333)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1114)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
at it.mycomp.myapp.seam.ActiveCompanies.getActiveCompanies(ActiveCompanies.java:76)
at it.mycomp.myapp.seam.ActiveCompanies$$EnhancerByCGLIB$$b3ecbcbf.CGLIB$getActiveCompanies$0(<generated>)
at it.mycomp.myapp.seam.ActiveCompanies$$EnhancerByCGLIB$$b3ecbcbf$$FastClassByCGLIB$$f6f04f39.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:167)
at org.jboss.seam.interceptors.JavaBeanInterceptor$1.proceed(JavaBeanInterceptor.java:80)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
at org.jboss.seam.interceptors.ValidationInterceptor.validateTargetComponent(ValidationInterceptor.java:64)
at sun.reflect.GeneratedMethodAccessor86.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
at org.jboss.seam.interceptors.OutcomeInterceptor.interceptOutcome(OutcomeInterceptor.java:21)
at sun.reflect.GeneratedMethodAccessor85.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
at org.jboss.seam.interceptors.RollbackInterceptor.rollbackIfNecessary(RollbackInterceptor.java:30)
at sun.reflect.GeneratedMethodAccessor84.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
at org.jboss.seam.interceptors.BijectionInterceptor.bijectTargetComponent(BijectionInterceptor.java:33)
at sun.reflect.GeneratedMethodAccessor83.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
at org.jboss.seam.interceptors.ConversationInterceptor.endOrBeginLongRunningConversation(ConversationInterceptor.java:68)
at sun.reflect.GeneratedMethodAccessor82.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
at org.jboss.seam.interceptors.BusinessProcessInterceptor.manageBusinessProcessContext(BusinessProcessInterceptor.java:60)
at sun.reflect.GeneratedMethodAccessor81.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
at org.jboss.seam.interceptors.TransactionInterceptor.doInTransactionIfNecessary(TransactionInterceptor.java:34)
at sun.reflect.GeneratedMethodAccessor80.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
at org.jboss.seam.interceptors.RemoveInterceptor.removeIfNecessary(RemoveInterceptor.java:39)
at sun.reflect.GeneratedMethodAccessor79.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
at org.jboss.seam.ejb.SeamInterceptor.aroundInvokeInContexts(SeamInterceptor.java:73)
at org.jboss.seam.ejb.SeamInterceptor.aroundInvoke(SeamInterceptor.java:45)
at org.jboss.seam.interceptors.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:51)
at org.jboss.seam.interceptors.JavaBeanInterceptor.intercept(JavaBeanInterceptor.java:39)
at it.mycomp.myapp.seam.ActiveCompanies$$EnhancerByCGLIB$$b3ecbcbf.getActiveCompanies(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:32)
at org.jboss.seam.Component.callComponentMethod(Component.java:1202)
at org.jboss.seam.Component.unwrap(Component.java:1218)
at org.jboss.seam.Component.getInstance(Component.java:1144)
at org.jboss.seam.Component.getInstance(Component.java:1114)
at org.jboss.seam.jsf.SeamVariableResolver.resolveVariable(SeamVariableResolver.java:44)
at org.apache.myfaces.config.LastVariableResolverInChain.resolveVariable(LastVariableResolverInChain.java:42)
at com.sun.facelets.el.LegacyELContext$LegacyELResolver.getValue(LegacyELContext.java:134)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:44)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:183)
at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
at com.sun.facelets.el.LegacyValueBinding.getValue(LegacyValueBinding.java:56)
at com.sun.facelets.component.UIRepeat.getValue(UIRepeat.java:143)
at com.sun.facelets.component.UIRepeat.getDataModel(UIRepeat.java:121)
at com.sun.facelets.component.UIRepeat.setIndex(UIRepeat.java:305)
at com.sun.facelets.component.UIRepeat.process(UIRepeat.java:333)
at com.sun.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:617)
at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:234)
at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:239)
at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.
15:36:05,968 ERROR [STDERR] java:540)
at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:384)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:138)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:23)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:45)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at it.mycomp.myapp.web.filter.ClientCacheDisableFilter.doFilter(ClientCacheDisableFilter.java:43)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
at java.lang.Thread.run(Thread.java:595)
Caused by: org.postgresql.util.PSQLException: ERROR: column "company0_.ragsoc" must appear in the GROUP BY clause or be used in an aggregate function
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1512)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1297)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:188)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:430)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:346)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:250)
at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:236)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1669)
at org.hibernate.loader.Loader.doQuery(Loader.java:662)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.doList(Loader.java:2145)
... 128 more
Name and version of the database you are using: postgresql 8.0The generated SQL (show_sql=true):Code:
select company0_.id as id17_, company0_.ragSoc as ragSoc17_, company0_.idLogo as idLogo17_, company0_.enabled as enabled17_, company0_.eMail as eMail17_, company0_.address1 as address6_17_, company0_.address2 as address7_17_, company0_.zip as zip17_, company0_.city as city17_, company0_.state as state17_, company0_.idCountry as idCountry17_, company0_.phone as phone17_, company0_.fax as fax17_, company0_.vat as vat17_, company0_.site as site17_
from comp.companies company0_ inner join prod.companyProducts products1_ on company0_.id=products1_.idCompany
where company0_.enabled=true
group by company0_.id
having count((products1_.idProduct, products1_.idCompany))>0
order by count((products1_.idProduct, products1_.idCompany)) desc