jamesfredley opened a new pull request, #15448:
URL: https://github.com/apache/grails-core/pull/15448
## Summary
Fixes #11464 - GORM `where` queries with local variable names matching
domain property names (e.g. `Book.where { title == title }`) fail with
`MissingMethodException` when called from `@Transactional` methods, but work
correctly outside of them.
See also: [GROOVY-9629](https://issues.apache.org/jira/browse/GROOVY-9629)
## Root Cause
Three-step AST transform interaction:
1. **DetachedCriteriaTransformer** (WHERE_ORDER priority) transforms `where
{ title == title }` into criteria API calls like `delegate.title(closure)` with
`implicitThis = true` (default in `MethodCallExpression` constructor).
2. **TransactionalTransform** runs later, moves the method body to
`$tt__methodName()`, then **re-runs Groovy's `VariableScopeVisitor`** on the
renamed method ([AbstractMethodDecoratingTransformation.groovy
L356-362](https://github.com/apache/grails-core/blob/7.0.x/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/transform/AbstractMethodDecoratingTransformation.groovy#L356-L362)).
3. **VariableScopeVisitor** sees `delegate.title(closure)` with
`implicitThis=true`, finds a local variable named `title` in scope, and
**rewrites** it to `title.call(closure)` - completely breaking the transformed
code.
## Fix
Set `implicitThis = false` on all `MethodCallExpression` nodes generated by
`DetachedCriteriaTransformer` where the object expression is `delegate`. This
is semantically correct - the call IS explicitly on `delegate`, not implicit
`this`. It prevents `VariableScopeVisitor` from rewriting the call.
**4 locations modified in `DetachedCriteriaTransformer.java`:**
- Association query on delegate (line ~790)
- Nested association chain traversal on delegate (line ~1064)
- Embedded property query on delegate (line ~1127)
- Domain association property query on delegate (line ~1161)
This pattern is already used in
`AbstractMethodDecoratingTransformation.groovy` (line 370) for similar reasons.
## Test Coverage
- **Unit tests**: 2 new tests in `WhereMethodSpec` verifying that
`@Transactional` + `@ApplyDetachedCriteriaTransform` classes with variable name
collisions compile and instantiate successfully
- **Functional tests**: 5 new integration tests in
`TransactionalWhereQueryVariableScopeSpec` verifying runtime behavior of where
queries with variable name collisions in `@Transactional` service methods
- All 82 existing `WhereMethodSpec` tests continue to pass
## Reproducer
A standalone reproducer application is available at:
https://github.com/jamesfredley/grails-where-query-transactional-scope-bug
--
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]