Before thinking about criteria, you first need to download the original SQL.
You can do this in SQL as follows (assuming there is a table AB connecting records between A and B , where fk_A points to id in A and fk_B points to id in B ):
SELECT fk_A, count(fk_B) FROM AB WHERE fk_B IN (b3, b5) GROUP BY fk_A HAVING count(fk_B) = 2
Thus, you will not get "incomplete" records from A , since the HAVING count(fk_B) operator filters them. Needless to say, you will have to replace 2 with the corresponding number if the number of Bs is different.
Next comes the hard bit of converting this to Criteria :) Some pseudo (read: unverified) code:
Criteria criteria = getSession().createCriteria(A.class); criteria.add(Restrictions.in("fk_B", new String[] {b3, b5})); ProjectionList projectionList = Projections.projectionList(); projectionList.add(Projections.count("fk_B")); projectionList.add(Projections.groupProperty("fk_A")); criteria.setProjection(projectionList);
As you can see, this criterion still skips the HAVING bit in it. Unfortunately, HAVING is not yet supported in the criteria API. However, you should get a list of results and counts and ignore those where the amount is less than required.
source share