Hi all,

My earlier message skipped the background, so here it is first.

Aliases in GORM criteria: what a query means when it names a collection twice

A criteria query can reach an association in two ways: an alias, 
createAlias('scores', 'a'), which names a join so a restriction can say 
a.round, or a block, scores { eq('round', 'first') }. Each one is a join of the 
association. The open question is what happens when one query uses several. 
Take an owner with a score in round one and another in round two:

    Pet.withCriteria {
        owner { scores { eq('round', 'first') } }
        owner { scores { eq('round', 'second') } }
    }

If the two blocks share a join, one score has to be in both rounds, so no pet 
matches. If each has its own join, the pet matches. Hibernate 5 shares them. 
Hibernate 7 on 8.0.x shared them in most shapes, but not in this nested one. 
Hibernate 5 also contradicts itself: for the same criteria it can return 
different rows depending on statement order, or on whether the criteria runs at 
the top or inside a subquery. It throws for 71% of the combinations we tested 
and contradicts itself for 7%, so it cannot be the reference.

A DetachedCriteria also dropped the first alias when a second was declared for 
the same association (#16851).

The rule, decided in https://github.com/apache/grails-core/issues/16889: blocks 
without an alias share one join. The first alias of an association path shares 
it, and every later alias has its own join, in the same block or another. An 
order by a path in a block that declares an alias for it sorts by that alias. 
To ask for two different elements, use two aliases.

The PRs: four open PRs (#16773, #16866, #16863 and #16559) collided in the same 
files, so they are consolidated with every author's commits kept: 
https://github.com/apache/grails-core/pull/16891 for Hibernate 7 on 8.0.x, and 
https://github.com/apache/grails-core/pull/16890 for the shared core part on 
7.0.x, which merges first. The core change is opt-in per datastore, so Mongo, 
Neo4j and the simple datastore behave as before. #16853 stays on its own. The 
suites and style checks pass, and the originals stay open until these are 
reviewed.

Any objection to the rule?

Walter

Reply via email to