I've checked in a new test case (com.avaje.tests.query.TestLimitQuery) which fails with a NPE due to the fact that the DefaultExpressionList.containsMany check is not able to correctly deal with Junctions which always returns null.
Seems like you have to drill down the expression tree to get in touch with all the used properties.
Care must be taken with in(name, Query) where you should NOT remove any many part of the passed in sub-query.
java.lang.NullPointerException at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768) at com.avaje.ebean.server.deploy.BeanDescriptor.getElPropertyDeploy(BeanDescriptor.java:1256) at com.avaje.ebean.util.DefaultExpressionList.containsMany(DefaultExpressionList.java:75) at com.avaje.ebean.server.querydefn.DefaultOrmQuery.isManyInWhere(DefaultOrmQuery.java:232) at com.avaje.ebean.server.core.DefaultServer.createQueryRequest(DefaultServer.java:1050) at com.avaje.ebean.server.core.DefaultServer.findList(DefaultServer.java:1291) at com.avaje.ebean.server.querydefn.DefaultOrmQuery.findList(DefaultOrmQuery.java:621) at com.avaje.tests.query.TestLimitQuery.testHasManyWithLimit(TestLimitQuery.java:28)
Committed up the fix into HEAD.
Test passing.
Code changed so that each expression handles whether is contains a 'Many' property with Junction type expressions checking all their contained expressions.
boolean SpiExpression.containsMany(BeanDescriptor desc)
Also note that the existence of a "Many" property expression can adjust how the SQL is generated (using distinct etc for findRowCount) but expressions are not removed.