Ошибка спящего режима из Projection.sum, когда сумма слишком велика для типа поля - PullRequest
4 голосов
/ 19 августа 2011

Я пытаюсь использовать проекцию для суммирования поля размера при группировании по роли.Критерии работают нормально, за исключением случаев, когда сумма больше не вписывается в тип поля размера.База данных, которую я использую MySQL, вернула больший тип для суммы, когда я запустил сгенерированный запрос непосредственно к базе данных, но я получил исключение из Hibernate.Поле размера является длинным в Java и BIGINT в MySQL.В любом случае можно ли заставить Hibernate возвращать больший тип, похоже, он пытается принудительно ввести сумму в тип суммируемого поля, даже если база данных возвращает его в большем типе.я получаю исключение:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLDataException: '12000010002048860160' in column '3' is outside valid range for the datatype BIGINT.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.6.0_21]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) ~[na:1.6.0_21]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) ~[na:1.6.0_21]
at java.lang.reflect.Constructor.newInstance(Constructor.java:513) ~[na:1.6.0_21]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.Util.getInstance(Util.java:384) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1027) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.ResultSetImpl.throwRangeException(ResultSetImpl.java:7970) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.ResultSetImpl.parseLongAsDouble(ResultSetImpl.java:7254) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.ResultSetImpl.getLong(ResultSetImpl.java:2944) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.ResultSetImpl.getLong(ResultSetImpl.java:2909) ~[mysql-connector-java.jar:na]
at com.mysql.jdbc.ResultSetImpl.getLong(ResultSetImpl.java:3021) ~[mysql-connector-java.jar:na]
at org.apache.commons.dbcp.DelegatingResultSet.getLong(DelegatingResultSet.java:278) ~[commons-dbcp.jar:1.4]
at org.apache.commons.dbcp.DelegatingResultSet.getLong(DelegatingResultSet.java:278) ~[commons-dbcp.jar:1.4]
at org.hibernate.type.descriptor.sql.BigIntTypeDescriptor$2.doExtract(BigIntTypeDescriptor.java:61) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:249) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:234) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.loader.criteria.CriteriaLoader.getResultColumnOrRow(CriteriaLoader.java:148) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:639) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:829) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2533) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.loader.Loader.list(Loader.java:2271) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347) ~[hibernate-core.jar:3.6.0.Final]
at com.netapp.dfm.entity.storage.WAFLDiskEntityManager.findDiskPhysicalSummaryForCluster(WAFLDiskEntityManager.java:153) ~[dfm-data-access.jar/:na]
at com.netapp.dfm.entity.storage.WAFLDiskEntityManager$$FastClassByCGLIB$$707d513f.invoke(<generated>) ~[cglib-nodep.jar:na]
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) ~[cglib-nodep.jar:na]
...

Ответы [ 3 ]

0 голосов
/ 19 августа 2011

Проблема связана с тем, что база данных пытается уместить сумму полей BIGINT в BIGINT, которая слишком мала, чтобы содержать значение (которое также не вписывается в java.lang.Long).

Чтобы обойти эту проблему, вы можете заменить прогноз на следующую сумму:

Projections.sqlProjection(
    "cast(sum({alias}.PHYSICAL_DISK) as number(30)) as SPACE", 
    new String[] { "SPACE" }, 
    new Type[] { BigIntegerType.INSTANCE })

(при условии, что свойство «физический диск» сопоставлено со столбцом «PHYSICAL_DISK» в вашей таблице).

Обратите внимание, я проверял это только в H2, а не в MySQL, но, учитывая, что в MySQL есть оператор приведения, принцип должен быть таким же.

0 голосов
/ 19 августа 2011

Hibernate изменил поведение в типах возврата для Projections.sum между версиями.Если вы используете версию Hibernate до 3.5, sum вернет целое число.3.5 и выше, он вернет Long.См. этот пост для получения дополнительной информации.Если у вас нет версии 3.5, переход на более новую версию может облегчить вашу проблему.

0 голосов
/ 19 августа 2011

Осторожно: НЕ ИСПЫТАНО

Реализация

Projections.sum() следующая:

return new AggregateProjection("sum", propertyName);

И AggregateProjection использует тип свойства как тип, возвращаемый функцией (сумма)

Вместо этого можно использовать пользовательский подкласс AggregateProjection, где метод getTypes переопределен, чтобы возвращать new Type[] {BigIntegerType.INSTANCE} вместо типа суммируемого свойства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...