HOW to use HAVING COUNT(*) with hibernate

Nicolas400 picture Nicolas400 · Dec 22, 2011 · Viewed 14.9k times · Source

I need to create a query and I need COUNT(*) and HAVING COUNT(*) = x.

I'm using a work around that uses the CustomProjection class, that I downloaded somewhere.

This is the SQL that I try to achieve:

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

This is the code, where I use the Projection Hibernate class:

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

The error is:

!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)

If I comment the line with CustomProjections class, the query work, but I don't get the HAVING COUNT(*) filter in the SQL ...

Basically the query try to retrieve, in a master - detail schema, all the master records where a list of details are simultaneously present, like if you want tho know "which invoices have both products, A and B".

That why if I got 3 items in the IN clause, I need to use HAVING COUNT = 3 clause.

Any idea or suggestion? Best regards,

Answer

Nicolas400 picture Nicolas400 · Dec 28, 2011

I figured out the problem. I replace CusotmProjections class, with:

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

where groupBy, alias and types are:

 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;

and the magic is on groupby String. –