jamesfredley opened a new pull request, #15699:
URL: https://github.com/apache/grails-core/pull/15699

   Fixes #15681
   
   ## Problem
   
   The Grails data binding guide states:
   
   > The "id" and "version" properties of a domain class are never bound by 
default.
   
   However, when a domain class extends an abstract base class that is **not** 
itself recognised as a domain class - for example an abstract `@DirtyCheck` 
class in `src/main/groovy` onto which GORM injects `id` and `version` (via 
`getFurthestUnresolvedParent()` during joint compilation) - `bindData` (and the 
map constructor) would bind `id` and `version` from the input.
   
   ## Root cause
   
   In `DefaultASTDatabindingHelper.getPropertyNamesToIncludeInWhiteList()`:
   
   1. The abstract base's whitelist is computed with `isDomainClass = false` 
(it has no `@Entity`/`@jakarta.persistence.Entity` annotation and is not under 
`grails-app/domain`). Because of that, `shouldFieldBeInWhiteList()` skips the 
`DOMAIN_CLASS_PROPERTIES_TO_EXCLUDE_BY_DEFAULT` check, so `id` and `version` 
are included in the base class' whitelist.
   2. When the domain subclass is processed, it inherits the parent whitelist 
into `bindablePropertyNames`.
   3. The field loop then short-circuits on 
`bindablePropertyNames.contains(fieldName)`, so `shouldFieldBeInWhiteList()` - 
which would correctly return `false` for `id`/`version` on a domain class - is 
never consulted. As a result `id` and `version` end up in the subclass' 
`$defaultDatabindingWhiteList`.
   
   ## Fix
   
   When the current class is a domain class, the default-excluded properties 
(`id`, `version`, `dateCreated`, `lastUpdated`) are no longer propagated from 
the inherited parent whitelist. An explicit `bindable: true` constraint 
declared on the domain class itself still re-enables binding, because 
constraints are processed after the inherited names are filtered.
   
   ## Tests
   
   Added a regression test to 
`DefaultASTDatabindingHelperDomainClassSpecialPropertiesSpec` that binds `id`, 
`version` and a regular property to a domain class extending a `@DirtyCheck` 
abstract base, asserting that `id`/`version` are not bound while the regular 
property is. The test fails before the fix and passes after.
   
   Verified no regressions across the existing data-binding suites 
(`grails-test-suite-web` binding/command-object/bindData specs and the 
persistence `GrailsWebDataBinderSpec`).
   


-- 
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]

Reply via email to