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]
