2011-08-18 2 views
4

역할별로 그룹화 할 때 크기 필드를 합산하기 위해 프로젝션을 사용하려고합니다. 크기가 더 이상 크기 필드의 유형에 맞지 않는 경우를 제외하고 조건이 정상적으로 작동합니다. 내가 MySQL을 사용하고있는 데이터베이스는 생성 된 쿼리를 데이터베이스에 대해 직접 실행했을 때 합계에 대해 더 큰 유형을 반환했지만 최대 절전 모드에서 예외가 발생했습니다. 크기 필드는 Java가 길고 MySQL의 BIGINT입니다. 어쨌든 더 큰 타입을 리턴하기 위해 Hibernate를 얻는 것이 어떨지, 데이터베이스가 더 큰 타입을 반환하더라도 합계가 필드의 타입으로 강제적으로 들어가도록 시도하는 것처럼 보인다.Projections.sum의 최대 절전 모드 오류가 필드 형식에 너무 큼

The projection portion of the criteria looks like this: 
List<Object[]> roleSummaries = session.createCriteria(PhysicalDisk.class) 
.setProjection(Projections.projectionList() 
.add(Projections.groupProperty(PhysicalDisk_.role), "role") 
.add(Projections.rowCount(), "count") 
.add(Projections.sum(PhysicalDisk_.totalBytes), "space") 
) 
.createCriteria(PhysicalDisk_.raidGroup, "raidGroup") 
.createCriteria("raidGroup." + RAIDGroup_.plex, "plex") 
.add(Restrictions.eq("plex." + Plex_.diskAggregate, diskAggregate)) 
.list(); 

나는 점점 오전 예외가 있습니다 :

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] 
... 

답변

0

가주의 :

return new AggregateProjection("sum", propertyName); 

그리고 AggregateProjection 용도 :

Projections.sum()의 구현은 테스트되지는 다음과 재산의 유형 대신 getTypes 방법 재정의 AggregateProjection의 서브 클래스 정의를 사용할 수있는 함수 (합)에 의해 반환 된 유형

같이 Y 대신 합산 속성 유형 new Type[] {BigIntegerType.INSTANCE}을 반환한다.

0

이 문제는 데이터베이스가 BIGINT 필드의 합을 값을 포함하기에는 너무 작은 BIGINT (이는 또한 java.lang.Long에 맞지 않음)에 맞추려고한다는 사실에서 기인합니다.

다음으로 합 투영을 대체 할 수있는이 문제를 회피하려면

(재산 "실제 디스크가"테이블에서 "PHYSICAL_DISK"컬럼에 매핑되는 것을 가정)
Projections.sqlProjection(
    "cast(sum({alias}.PHYSICAL_DISK) as number(30)) as SPACE", 
    new String[] { "SPACE" }, 
    new Type[] { BigIntegerType.INSTANCE }) 

.

참고 :이 테스트는 MySQL이 아닌 H2에서만했지만 MySQL에 캐스트 연산자가 있다고 가정 할 때 원칙은 동일해야합니다.

0

Hibernate는 버전 간 Projections.sum의 반환 유형에서 동작이 변경되었습니다. 3.5 이전에 Hibernate 버젼을 사용하고 있다면, sum은 Integer를 반환 할 것이다. 3.5 이상이면 Long을 반환합니다. 자세한 내용은 this post을 참조하십시오. 3.5가 아닌 경우 최신 버전으로 이전하면 문제가 완화 될 수 있습니다.

+0

그게 도움이되지 않습니다, 문제는 합계가 길지는 않지만 BigInteger에 들어야한다는 것입니다. – MillerM