2011-01-11 6 views
2

verwendet werden Ich habe einige Probleme mit einer SQL-Abfrage. Ich verwende Hibernate-Kriterien zum Erstellen der Abfrage. Ich erstelle einige Bins aus einer Datenbank, indem ich die Werte mit bestimmten Intervallen (der binSize) abrundet und sie dann gruppiert. Dies funktioniert gut, wenn es es direkt in SQL mit der Abfrage versuchen:Fehler: Spalte "This_.phitorsionangle" muss in der GROUP BY-Klausel angezeigt oder in einer Aggregatfunktion

 
SELECT floor(phiTorsionAngle/2) * 2 as phiTorsionAngleBin, 
     floor(psiTorsionAngle/2) * 2 as psiTorsionAngleBin, 
     floor(phiTorsionAngle/2) + 180 as phiTorsionAngleBinIndex, 
     floor(psiTorsionAngle/2) + 180 as psiTorsionAngleBinIndex, 
     count(*) as numberOfResidues 
FROM residue 

WHERE phitorsionangle IS NOT NULL 
    AND psitorsionangle IS NOT NULL 

GROUP BY phiTorsionAngleBin, psiTorsionAngleBin 

Aber wenn ich es mit Hibernate Kriterien versuchen, es funktioniert nicht. Dies ist der Code, um die Abfrage zu erstellen:

ScrollableResults phiPsiBins = createCriteria() 
.setProjection(Projections.projectionList() 
     .add(Projections.sqlGroupProjection(
     "floor(phiTorsionAngle/" + binSize + ") * " + binSize + " as phiTorsionAngleBin, " + 
     "floor(psiTorsionAngle/" + binSize + ") * " + binSize + " as psiTorsionAngleBin, " +   
     "floor(phiTorsionAngle/" + binSize + ") + 180 as phiTorsionAngleBinIndex, " + 
     "floor(psiTorsionAngle/" + binSize + ") + 180 as psiTorsionAngleBinIndex, " + 
     "count(*) as numberOfResidues", 
     "phiTorsionAngleBin, psiTorsionAngleBin", 
     new String[] {"phiTorsionAngleBin", "psiTorsionAngleBin", "phiTorsionAngleBinIndex", "psiTorsionAngleBinIndex", "numberOfResidues"}, 
     new Type[] {Hibernate.DOUBLE, Hibernate.DOUBLE, Hibernate.INTEGER, Hibernate.INTEGER, Hibernate.INTEGER}))) 
.add(Restrictions.isNotNull("phiTorsionAngle")) 
.add(Restrictions.isNotNull("psiTorsionAngle")) 
.setResultTransformer(Transformers.aliasToBean(PhiPsiBinResult.class)) 
.setCacheMode(CacheMode.IGNORE) 
.scroll(ScrollMode.FORWARD_ONLY); 

Dies ist die Fehlermeldung erhalte ich mit der vollen stacktrace darunter:

 
ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function 

WARN 2011-01-11 16:13:43,047 main JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 42803 
ERROR 2011-01-11 16:13:43,047 main JDBCExceptionReporter:101 - ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function 
    Position: 143 
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query using scroll 
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90) 
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
at org.hibernate.loader.Loader.scroll(Loader.java:2340) 
at org.hibernate.loader.criteria.CriteriaLoader.scroll(CriteriaLoader.java:113) 
at org.hibernate.impl.SessionImpl.scroll(SessionImpl.java:1561) 
at org.hibernate.impl.CriteriaImpl.scroll(CriteriaImpl.java:320) 
at nl.ru.cmbi.pdbeter.core.controller.DAO.ResidueDAO.getPhiPsiBinSet(ResidueDAO.java:236) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:616) 
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
at $Proxy27.getPhiPsiBinSet(Unknown Source) 
at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsFunctions.makeRamachandranPlot(StatisticsFunctions.java:26) 
at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsMain.start(StatisticsMain.java:39) 
at nl.ru.cmbi.pdbeter.statistics.controller.StatisticsMain.main(StatisticsMain.java:33) 
Caused by: org.postgresql.util.PSQLException: ERROR: column "this_.phitorsionangle" must appear in the GROUP BY clause or be used in an aggregate function 
    Position: 143 
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062) 
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795) 
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:271) 
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208) 
at org.hibernate.loader.Loader.getResultSet(Loader.java:1812) 
at org.hibernate.loader.Loader.scroll(Loader.java:2305) 
... 18 more 

ich Zugabe versucht, die phiTorsionAngle und psiTorsionAngle an die GROUP BY, und das scheint zu funktionieren, aber es macht keinen Sinn, das zu tun. Ich möchte nicht nach jedem möglichen Wert für phiTorsionAngle gruppieren, ich möchte nach dem gesamten Bin gruppieren, wahrscheinlich mit vielen verschiedenen Werten für phiTorsionAngle. Warum gibt es mir diesen Fehler und wie arbeite ich daran?

UPDATE: Ich habe eigentlich nicht versucht, die Abfrage laufen zu lassen, bis es fertig war, und ich bekam einen Java-Fehler wegen Heap-Speicher, weil es versuchte, etwa 19 Millionen Einträge zu laden, also phiTorsionAngle und psiTorsionAngle zu der Gruppierung ist jetzt völlig außer Frage :)

+0

Versuchen Sie, SQL-Protokollierung zu aktivieren: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/session- configuration.html # configuration-logging – axtavt

Antwort

0
SELECT phiTorsionAngleHalfFloor * 2 as phiTorsionAngleBin, 
     psiTorsionAngleHalfFloor * 2 as psiTorsionAngleBin, 
     phiTorsionAngleHalfFloor + 180 as phiTorsionAngleBinIndex, 
     psiTorsionAngleHalfFloor + 180 as psiTorsionAngleBinIndex, 
     numberOfResidues 
FROM (
     SELECT FLOOR(phiTorsionAngleHalf/2) AS phiTorsionAngleHalfFloor, 
       FLOOR(psiTorsionAngleHalf/2) AS psiTorsionAngleHalfFloor, 
       COUNT(*) AS numberOfResidues 
     FROM residue 
     WHERE phitorsionangle IS NOT NULL 
       AND psitorsionangle IS NOT NULL 
     GROUP BY 
       phiTorsionAngleHalfFloor, psiTorsionAngleHalfFloor 
     ) q 
+0

Ich denke, ich werde nicht klar genug: Ich kann nicht gruppieren mit dem phiTorsionAngle oder psiTorsionAngle, weil das den Zweck der Abfrage vereitelt. Ich brauche Gruppen von phiTorsionAngleBin und psiTorsionAngleBin. Außerdem, wie Sie in meinem Update lesen können: Wenn Sie das tun, was Sie in Java sagen, führt dies zu einem Heap-Speicherfehler, weil es versucht, etwa 19 Millionen Ergebnisse in den Speicher zu laden. – FinalArt2005

+0

@FinalArt: Sorry, habe dein Modell falsch verstanden. Siehe das Post-Update. – Quassnoi