jdaugherty commented on code in PR #16573:
URL: https://github.com/apache/grails-core/pull/16573#discussion_r4360519138
##########
grails-data-hibernate7/core/src/test/groovy/grails/gorm/tests/BasicCollectionInQuerySpec.groovy:
##########
@@ -139,17 +139,22 @@ class BasicCollectionInQuerySpec extends Specification {
s3.addToSchools("Columbia")
s3.save(flush: true)
- when: "an alias is explicitly created before using in() with the raw
property name"
+ when: "an alias is explicitly created before restricting the
collection or the alias"
def results = BcStudent.createCriteria().list {
createAlias("schools", "sch")
- 'in'('schools', ['Princeton'])
+ 'in'(restrictedPath, ['Princeton'])
projections {
property 'email'
}
}
- then: "the existing alias is reused instead of creating a duplicate"
- results.sort() == ['[email protected]', '[email protected]']
+ then: "collection membership leaves the alias independent, while an
alias restriction filters its elements"
+ results.sort() == expectedEmails
+
+ where:
+ restrictedPath | expectedEmails
+ 'schools' | ['[email protected]', '[email protected]', '[email protected]']
Review Comment:
Commenting on this expectation: since `createContext` materializes every
explicit alias, an unused basic-collection alias now joins, and that changes
results 8.0.x returns. With `Student { String name; static hasMany = [schools:
String] }`, Grace at Yale and Princeton, Hank at Princeton, and None with no
schools:
| Query | 8.0.x (0e8fd03e56) | this head |
|---|---|---|
| `createAlias('schools', 's'); 'in'('schools', ['Princeton'])`, names |
`[grace, hank]` | `[grace, grace, hank]` |
| the same, `count()` | 2 | 3 |
| `createAlias('schools', 's')` alone, names | `[grace, hank, none]` |
`[grace, grace, hank]` |
| `createAlias('schools', 's', 1)` alone, names | `[grace, hank, none]` |
`[grace, grace, hank, none]` |
The first two are the duplicate-row symptom #16562 is about: the unused
alias becomes `join student_schools s1_0`, while the `in` stays a separate
`exists (...)`, so every row of `s1_0` survives.
Materializing only entity aliases keeps all four at their 8.0.x values:
```java
for (HibernateAlias alias : aliases) {
if
(!(detachedCriteria.getPersistentEntity().getPropertyByName(alias.path())
instanceof Basic)) {
context.getFullyQualifiedExpression(alias.alias());
}
}
```
With that change in a local probe (not pushed), the full
`:grails-data-hibernate7-core:test` has one failure: this test, which goes back
to its original `['[email protected]', '[email protected]']`. Your unreferenced
`favorite` alias tests still pass, and so does the rest of
`CreateAliasJoinSpec`, including `basic collection membership remains
independent of an element alias`. Entity aliases keep the new behaviour without
changing an 8.0.x result: there a single unused entity alias already joined
through its association criteria, and two aliases of one entity path threw.
Please restore this test's original expectation, drop the "An unused
basic-collection alias still contributes its element join" paragraph from
`criteria.adoc`, and narrow "every explicitly requested alias creates a join"
(`criteria.adoc:157`, `createCriteria.adoc:101`) to aliases of entity
associations.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]