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

   ## Summary
   
   Fixes #15680.
   
   When a domain property has both `index: true, indexAttributes: [unique: 
true]` in `static mapping` and `unique: true` in `static constraints`, the 
constraint evaluation overwrites the mapping-configured property, so the 
database-level unique index is silently never created.
   
   ## Root Cause
   
   `AbstractGormMappingFactory.createMappedForm()` evaluates both closures 
through the same `DefaultMappingConfigurationBuilder`:
   1. The mapping closure (`name index: true, indexAttributes: [unique: true]`) 
goes through `builder.invokeMethod`, which stores a `MongoAttribute` with 
`index=true, indexAttributes={unique:true}` in `builder.properties['name']`.
   2. The constraint closure (`name unique: true`) goes through 
`Entity.methodMissing`, which creates a SEPARATE instance in 
`target.propertyConfigs['name']` containing only `unique=true`.
   3. `builder.getProperties()` then does 
`properties.putAll(target.propertyConfigs)`, overwriting the mapping-set 
property with the constraint-only version. `index` reverts to `false` and 
`indexAttributes` becomes `null`.
   
   `MongoDatastore.initializeIndices()` reads 
`property.getMapping().getMappedForm().isIndex()`, which now returns `false`, 
so the MongoDB index is silently never created.
   
   ## Fix
   
   Change `getProperties()` to use `putIfAbsent` semantics — properties already 
configured by the mapping closure are preserved when the constraint closure 
provides a conflicting entry.
   
   ## Test
   
   `DefaultMappingConfigurationBuilderSpec` covers the scenario directly: a 
property simulating GORM's `Entity.methodMissing` path against a builder that 
already has a mapping-configured property. The test FAILS before the fix and 
PASSES after.
   
   ## Verified
   
   Tested against a real Pixoto3 Grails 7.2 app with embedded MongoDB:
   - Before: `Category.name` declared `index: true, indexAttributes: [unique: 
true]` in mapping + `unique: true` in constraints → only `_id_` index in MongoDB
   - After: same declarations → `name_1` unique index correctly created in 
MongoDB
   
   ## Backward Compatibility
   
   Behavior change: if a user previously relied on constraints overwriting 
mapping (unlikely — that's the bug), they would observe their 
mapping-configured property surviving instead. The opposite direction 
(constraint values being applied on top of an existing mapping property) was 
already happening through `builder.invokeMethod` reusing the existing instance, 
so the typical "add a constraint to a mapped property" flow is unaffected.


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