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

   ## What
   
   Makes the framework `grailsDomainClassMappingContext` bean **deferrable**, 
and converts GORM-MongoDB to register its mapping context via 
auto-configuration so the framework fallback backs off cleanly — replacing the 
current "register a context the framework then yields to" approach with a 
single, well-defined owner.
   
   ## Background
   
   `GrailsDomainClassAutoConfiguration` registers a fallback 
`grailsDomainClassMappingContext` (a `DefaultMappingContextFactoryBean`) for 
apps with domain classes but no GORM datastore. When a datastore is present it 
supersedes that bean. How it supersedes differs per datastore:
   
   - **Hibernate** registers a same-named bean definition 
(`grailsDomainClassMappingContext(hibernateDatastore:"getMappingContext")`) → a 
genuine bean-definition override (logs `Overriding bean definition for bean 
'grailsDomainClassMappingContext'`).
   - **MongoDB / Neo4j** register their own context (`mongoMappingContext`) and 
add an alias `grailsDomainClassMappingContext` → the fallback definition is 
silently shadowed by the alias (no log; being `@Lazy` it never instantiates), 
leaving an orphaned definition under a name that is also an alias.
   
   This PR addresses the MongoDB case and adds the reusable enabling change in 
grails-core. Other datastores can follow the same pattern.
   
   ## Changes
   
   **grails-core** (behaviour-neutral on its own):
   - `GrailsDomainClassAutoConfiguration.grailsDomainClassMappingContext` is 
now `@ConditionalOnMissingBean(name = 'grailsDomainClassMappingContext')`. The 
condition is evaluated by `ConfigurationClassPostProcessor`, before 
`GrailsApplicationPostProcessor` runs any `doWithSpring`, so with no datastore 
the fallback still registers exactly as before.
   
   **grails-data-mongodb**:
   - New `MongoMappingContextAutoConfiguration` registers the 
`MongoMappingContext` as `mongoMappingContext` with the 
`grailsDomainClassMappingContext` alias, ordered `beforeName` 
`GrailsDomainClassAutoConfiguration` so the framework fallback backs off. It 
builds the context via `MongoDatastore.createMappingContext(config, classes)`, 
so it is identical (settings + validation registry) to the one the datastore 
would build.
   - `MongoDatastore.createMappingContext(PropertyResolver, Class...)` is now 
`public`, so the auto-configuration builds the same context the datastore uses.
   - `MongoDbDataStoreSpringInitializer` detects a pre-registered 
`mongoMappingContext` and builds `mongoDatastore` around it (new 
`MongoDatastore(config, connectionSourceFactory, mappingContext, publisher)` 
for the default path; the existing `MongoDatastore(client, config, 
mappingContext, publisher)` for the supplied-client path) instead of 
re-registering its own. A single context is shared. Standalone (non-Grails) 
bootstrap is unchanged; secondary datastores keep their existing path.
   - Adds the `MongoDatastore(PropertyResolver, MongoConnectionSourceFactory, 
MongoMappingContext, ConfigurableApplicationEventPublisher)` constructor.
   
   ## Result
   
   For a Grails + MongoDB app, `grailsDomainClassMappingContext` resolves to a 
single, datastore-shared context owned by the auto-configuration, with no 
orphaned/shadowed fallback definition. (Mongo emitted no override log before 
this change — it superseded via an alias — so this is a registry-cleanliness 
improvement, not the removal of a log line.)
   
   ## Tests
   
   `MongoDbDataStoreSpringInitializerSpec` (MongoDB testcontainer), new case: 
the datastore reuses a pre-registered `mongoMappingContext` (object identity), 
the bean is not overridden, the `grailsDomainClassMappingContext` alias 
resolves to the same single instance, and an entity round-trips. Existing 
standalone cases (custom codecs from Spring, custom type marshallers, 
primary/secondary alias, geo/constraints) still pass.
   
   ## Follow-ups
   
   - An app-slice test asserting the auto-configuration ordering makes the 
fallback back off in a real Spring Boot context (this PR's test simulates the 
pre-registered bean directly).
   - The same pattern for Hibernate — where the visible `Overriding bean 
definition` log originates — is harder because its mapping context is bound to 
the `SessionFactory`, and is left for a separate change.
   


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