hibernate having-clause

select count hibernate



CÓMO usar TENER COUNT(*) con Hibernate (4)

Necesito crear una consulta y necesito COUNT(*) y HAVING COUNT(*) = x .

Estoy usando una CustomProjection que usa la clase CustomProjection , que descargué en algún lugar.

Este es el SQL que trato de lograr:

select count(*) as y0_, this_.ensayo_id as y1_ from Repeticiones this_ inner join Lineas linea1_ on this_.linea_id=linea1_.id where this_.pesoKGHA>0.0 and this_.nroRepeticion=1 and linea1_.id in (18,24) group by this_.ensayo_id having count(*) = 2

Este es el código, donde utilizo la clase Projection Hibernate:

critRepeticion.setProjection(Projections.projectionList() .add( Projections.groupProperty("ensayo") ) .add( CustomProjections.groupByHaving("ensayo_id",Hibernate.LONG,"COUNT(ensayo_id) = "+String.valueOf(lineas.size())) .add( Projections.rowCount() ) );

El error es:

!STACK 0 java.lang.NullPointerException at org.hibernate.criterion.ProjectionList.toSqlString(ProjectionList.java:50) at org.hibernate.loader.criteria.CriteriaQueryTranslator.getSelect(CriteriaQueryTranslator.java:310) at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:71) at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:67) at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1550) at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283) at ar.com.cse.cseagro.controller.RepeticionController.buscarEnsayo(RepeticionController.java:101)

Si comento la línea con la clase CustomProjections , la consulta funciona, pero no obtengo el filtro HAVING COUNT(*) en el SQL ...

Básicamente, la consulta intenta recuperar, en un esquema maestro - detalle, todos los registros maestros donde una lista de detalles está presente simultáneamente, como si usted quisiera saber "qué facturas tienen ambos productos, A y B".

Por eso, si obtuve 3 elementos en la cláusula IN , necesito usar la cláusula HAVING COUNT = 3 .

Alguna idea o sugerencia? Atentamente,


Resolví el problema. Sustituyo la clase CusotmProjections con:

.add( Projections.sqlGroupProjection("ensayo_id", groupBy , alias, types));

donde groupBy, alias y tipos son:

String groupBy = "ensayo_id" + " having " + "count(*) = " + String.valueOf(lineas.size()); String[] alias = new String[1]; Alias[0] = "ensayo_id"; Type[] types = new Type[1]; types[0] = Hibernate.INTEGER;

y la magia está en groupby String. -


Si alguien necesita hacerlo en grial sería como:

projections { groupProperty("id") sqlGroupProjection(...) rowCount() }

Donde sqlGroupProjection está disponible desde 2.2.0

/** * Adds a sql projection to the criteria * * @param sql SQL projecting * @param groupBy group by clause * @param columnAliases List of column aliases for the projected values * @param types List of types for the projected values */ protected void sqlGroupProjection(String sql, String groupBy, List<String> columnAliases, List<Type> types) { projectionList.add(Projections.sqlGroupProjection(sql, groupBy, columnAliases.toArray(new String[columnAliases.size()]), types.toArray(new Type[types.size()]))); }

http://grepcode.com/file/repo1.maven.org/maven2/org.grails/grails-hibernate/2.2.0/grails/orm/HibernateCriteriaBuilder.java/#267


criteria.add (Restrictions.sqlRestriction ("1 = 1 que tiene count (*) = 2"));


Aquí está mi muestra, funciona bien, tal vez sea útil:

Mi consulta sql:

seleccione COLUMN1, suma (COLUMN2) del grupo MY_TABLE por COLUMN1 con suma (COLUMN2)> 1000;

Y Criteria sería:

Criteria criteria = getCurrentSession().createCriteria(MyTable.Class); ProjectionList projectionList = Projections.projectionList(); projectionList.add(Projections.property("column1"), "column1"); projectionList.add(Projections.sqlGroupProjection("sum(column2) sumColumn2 ", "COLUMN1 having sum(COLUMN2) > 1000" , new String[]{"sumColumn2"}, new org.hibernate.type.Type[]{StandardBasicTypes.STRING})); criteria.setProjection(projectionList); criteria.List();