.selectNew().withSubquery() does't seem to work properly
Description
I'm trying to use the criteria builder "select new" feature together with a subquery. In a simplified example along the lines of:
CriteriaBuilder<CatModel> cb = cbf.create(em, Tuple.class)
.from(Cat.class, "cat")
.selectNew(CatModel.class)
.with("cat.name")
.withSubquery("offspring")
.from(Cat.class, "child")
.select("COUNT(*)")
.where("child.mother.id").eqExpression("cat.id")
.end()
.with("cat.age")
.end();
Expected behavior
I would expect the method getResultList() to query the database and create a list of CatModel instances, calling the constructor with the result of the subquery among the other arguments.
Actual behavior
An exception is thrown when the query is built:
com.blazebit.persistence.impl.BuilderChainingException: A builder was not ended properly.
at com.blazebit.persistence.impl.builder.object.SelectObjectBuilderImpl.verifySubqueryBuilderEnded(SelectObjectBuilderImpl.java:110)
at com.blazebit.persistence.impl.builder.object.SelectObjectBuilderImpl.with(SelectObjectBuilderImpl.java:79)
at com.blazebit.persistence.impl.builder.object.SelectObjectBuilderImpl.with(SelectObjectBuilderImpl.java:70)
...
I suspect that subqueryStartMarker in SelectObjectBuilderImpl should be reset in onBuilderEnded() in a similar way that multipleSubqueryStartMarker is reset.
Steps to reproduce
I have not created a special test case that I could share, yet. But I will do so if it actually helps in this case.
Environment
Version: 1.6.8 JPA-Provider: Hibernate 5.6.14.Final DBMS: Oracle 11g Application Server: Tomcat, Spring Framework
Hi there. Do you understand that the parameter you pass to withSubquery() is the select item alias? Could you try omitting that for the sake of testing?
Also, did you try using the withSubqueries() as a workaround yet i.e. .withSubqueries("mysubquery").with("mysubquery")...end()?
We actually have a test for this, which is why I am a bit surprised that you run into this. See https://github.com/Blazebit/blaze-persistence/blob/08793f4ab72cd57762bb6d222ad1fa9421f23e22/core/testsuite/src/test/java/com/blazebit/persistence/testsuite/SelectNewTest.java#L110-L109
Would be cool if you could create a PR with a test case that shows the error, preferably by adding a method like the one I pointed you to.
Thanks for the blazingly fast response! I was indeed going to try withSubqueries() next, but I'll be caught up in meetings for the rest of the day. I will get back to you on those points by tomorrow.
Omitting the select alias did not change the behavior, but I can indeed work around the issue for now by using withSubqueries().
The error occurs only if the withSubquery() is followed by another select item. It seems to go unnoticed in cases where the withSubquery() item is the last one in the list.
I added two additional test methods as you suggested and I will create a PR, shortly. I actually don't use Github very often so I hope I'm doing it right.
Great work, thanks for the reproducer. I'll look as soon as I can!