2011-12-22 9 views
8

Necesito crear una consulta y necesito COUNT(*) y HAVING COUNT(*) = x.CÓMO usar TENER COUNT (*) con hibernación

Estoy usando un trabajo que utiliza 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 CustomProjections clase, la consulta funciona, pero no entiendo t l filtro HAVING COUNT(*) en el SQL ...

Básicamente, la consulta intenta recuperar, en un esquema de detalle maestro, 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 tengo 3 elementos en la cláusula IN, necesito usar la cláusula HAVING COUNT = 3.

¿Alguna idea o sugerencia? Saludos cordiales,

+0

En este momento, me di cuenta del problema. Sustituyo la clase CusotmProjections con: .add (Proyecciones.sqlGroupProjection ("ensayo_id", groupBy, alias, tipos)), donde groupBy, alias y tipos son: \t \t \t String groupBy = "ensayo_id" + "having" + "count (*) =" + String.valueOf (lineas. tamaño()); \t \t \t Cadena [] alias = new Cadena [1]; \t \t \t alias [0] = "ensayo_id"; \t \t \t Tipo [] types = new Type [1]; \t \t \t tipos [0] = Hibernate.INTEGER; y la magia está en groupby String. – Nicolas400

Respuesta

9

Descubrí el problema. Sustituyo 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 Cadena GroupBy. -

1

Si alguien tiene que hacerlo en griales que sería como:

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

Dónde 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

0

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

2

Aquí es mi muestra, que funciona bien, puede resultar útil:

Mi consulta SQL:

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

y criterios serían:

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();