jamesfredley opened a new issue, #15416:
URL: https://github.com/apache/grails-core/issues/15416
## Summary
`AbstractWhereImplementer.doImplement()` calls
`findConnectionId(newMethodNode)` instead of
`findConnectionId(abstractMethodNode)`, which means `@Where`-annotated methods
on Data Services with class-level `@Transactional(connection = '...')` will
silently route queries to the default datasource instead of the specified
connection.
## Root Cause
In `AbstractWhereImplementer.groovy` line 99:
```groovy
Expression connectionId = findConnectionId(newMethodNode)
```
`findConnectionId` resolves the `@Transactional` annotation via
`TransactionalTransform.findTransactionalAnnotation(methodNode)`, which falls
back to `methodNode.getDeclaringClass()`. The `newMethodNode` (the generated
implementation method) declares on the generated impl class, which does not
carry the `@Transactional` annotation. The `abstractMethodNode` (the original
interface/abstract class method) declares on the class that has the annotation.
This causes `findConnectionId` to return null, so the
`withConnection(connectionId)` call on the DetachedCriteria is never added, and
the query runs against the default datasource.
## Affected Code
`grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/services/implementers/AbstractWhereImplementer.groovy`
## Example
```groovy
@Service(Metric)
@Transactional(connection = 'secondary')
interface MetricDataService {
@Where({ timestamp >= from })
List<Metric> findAfter(Date from)
}
```
`findAfter()` will query the default datasource instead of `secondary`.
## Fix
Change line 99 from:
```groovy
Expression connectionId = findConnectionId(newMethodNode)
```
to:
```groovy
Expression connectionId = findConnectionId(abstractMethodNode)
```
Both `abstractMethodNode` and `newMethodNode` are available in the
`doImplement` method signature.
## Context
Discovered while fixing the same bug pattern in PR #15395. That PR fixed
`SaveImplementer`, `DeleteImplementer`, `FindAndDeleteImplementer`, and
`AbstractDetachedCriteriaServiceImplementor`. The `AbstractWhereImplementer`
instance was pre-existing on the `7.0.x` branch.
--
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]