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]