У меня возникли проблемы с SQL-запросом.Я использую Hibernate Criteria для построения запроса.Я создаю несколько ячеек из базы данных, округляя значения с определенными интервалами (binSize), а затем группирую их.Это прекрасно работает, когда я пробую это напрямую в SQL с запросом:
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
Но когда я пробую это с Hibernate Criteria, это терпит неудачу.Это код для построения запроса:
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);
Это сообщение об ошибке, которое я получаю, с полной трассировкой стека под ним:
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
Я попытался добавить phiTorsionAngle иpsiTorsionAngle для GROUP BY, и это, кажется, работает, но это не имеет смысла делать это.Я не хочу группировать по каждому возможному значению phiTorsionAngle, я хочу сгруппировать по всему бину, возможно, содержащему много разных значений для phiTorsionAngle.Почему это дает мне эту ошибку и как мне ее обойти?
ОБНОВЛЕНИЕ: Я на самом деле не пытался запустить запрос, пока он не был завершен, и я получил Java из-за ошибки пространства кучипотому что он попытался загрузить около 19 миллионов записей, поэтому о добавлении phiTorsionAngle и psiTorsionAngle в группировку теперь совершенно не может быть и речи:)