This is an automated email from the ASF dual-hosted git repository.

borinquenkid pushed a commit to branch test/abstract-datastore-initializer
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit eec3be04f04af61beb7b2ed2678f871fd9ed29bd
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Thu Aug 13 16:07:40 2026 -0500

    Fix setDatabaseName being silently ignored on 
MongoDbDataStoreSpringInitializer
    
    MongodbGrailsPlugin sets initializer.databaseName = applicationName to
    default the Mongo database name to the Grails app's name, but that field
    was never read anywhere - every Grails+MongoDB app not explicitly setting
    grails.mongodb.databaseName silently got the wrong database.
    
    Adds applyDatabaseNameFallback(), called at the top of getBeanDefinitions()
    (the only method MongodbGrailsPlugin actually invokes - it doesn't go
    through configure()), which injects databaseName as a
    grails.mongodb.databaseName fallback property on `configuration` only when
    it was customized away from the class default and the configuration
    doesn't already specify one explicitly. Handles both configuration shapes
    this class accepts: ConfigurableEnvironment (the default and the
    Map-constructor path, both mutable via propertySources) and a generic Map
    (covering Grails' own Config, which this module can't depend on directly
    since it's designed to work standalone outside Grails - tested here via a
    minimal Map+PropertyResolver double instead).
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
---
 .../MongoDbDataStoreSpringInitializer.groovy       |  23 ++++
 .../MongoDbDataStoreSpringInitializerSpec.groovy   |  39 +++++++
 ...ongoDbDataStoreSpringInitializerUnitSpec.groovy | 122 +++++++++++++++++++++
 3 files changed, 184 insertions(+)

diff --git 
a/grails-data-mongodb/core/src/main/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializer.groovy
 
b/grails-data-mongodb/core/src/main/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializer.groovy
index 7672e0fe8e..98f43a5e90 100644
--- 
a/grails-data-mongodb/core/src/main/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializer.groovy
+++ 
b/grails-data-mongodb/core/src/main/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializer.groovy
@@ -25,6 +25,8 @@ import org.springframework.context.ApplicationContext
 import org.springframework.context.ApplicationEventPublisher
 import org.springframework.context.ConfigurableApplicationContext
 import org.springframework.context.support.GenericApplicationContext
+import org.springframework.core.env.ConfigurableEnvironment
+import org.springframework.core.env.MapPropertySource
 import org.springframework.util.ClassUtils
 
 import grails.mongodb.MongoEntity
@@ -36,6 +38,7 @@ import 
org.grails.datastore.gorm.support.AbstractDatastorePersistenceContextInte
 import org.grails.datastore.gorm.support.DatastorePersistenceContextInterceptor
 import 
org.grails.datastore.mapping.config.DatastoreServiceMethodInvokingFactoryBean
 import org.grails.datastore.mapping.mongo.MongoDatastore
+import org.grails.datastore.mapping.mongo.config.MongoSettings
 import 
org.grails.datastore.mapping.mongo.connections.MongoConnectionSourceFactory
 
 /**
@@ -83,8 +86,28 @@ class MongoDbDataStoreSpringInitializer extends 
AbstractDatastoreInitializer {
         return applicationContext
     }
 
+    /**
+     * Applies {@link #databaseName} as a {@code grails.mongodb.databaseName} 
fallback on
+     * {@link #configuration} when it was customized via {@link 
#setDatabaseName(String)} and the
+     * configuration does not already specify a database name explicitly.
+     */
+    protected void applyDatabaseNameFallback() {
+        if (databaseName == DEFAULT_DATABASE_NAME || 
configuration.containsProperty(MongoSettings.SETTING_DATABASE_NAME)) {
+            return
+        }
+        if (configuration instanceof ConfigurableEnvironment) {
+            ((ConfigurableEnvironment) configuration).propertySources.addFirst(
+                    new 
MapPropertySource('mongoDbDataStoreSpringInitializer.databaseName', 
[(MongoSettings.SETTING_DATABASE_NAME): databaseName])
+            )
+        }
+        else if (configuration instanceof Map) {
+            ((Map) configuration).put(MongoSettings.SETTING_DATABASE_NAME, 
databaseName)
+        }
+    }
+
     @Override
     Closure getBeanDefinitions(BeanDefinitionRegistry beanDefinitionRegistry) {
+        applyDatabaseNameFallback()
         return {
             def callable = getCommonConfiguration(beanDefinitionRegistry, 
'mongo')
             callable.delegate = delegate
diff --git 
a/grails-data-mongodb/core/src/test/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializerSpec.groovy
 
b/grails-data-mongodb/core/src/test/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializerSpec.groovy
index 300d447ab7..5b33af0e38 100644
--- 
a/grails-data-mongodb/core/src/test/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializerSpec.groovy
+++ 
b/grails-data-mongodb/core/src/test/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializerSpec.groovy
@@ -61,6 +61,45 @@ class MongoDbDataStoreSpringInitializerSpec extends 
AutoStartedMongoSpec {
         mongoDatastore.destroy()
     }
 
+    void "Test setDatabaseName is honored as a fallback when no explicit 
grails.mongodb.databaseName is configured"() {
+        given: "an initializer with a customized database name and no explicit 
database name config"
+        def initializer = makeInitializer([
+                (MongoSettings.SETTING_HOST): mongoHost,
+                (MongoSettings.SETTING_PORT): mongoPort,
+        ], Person)
+        initializer.setDatabaseName('fallbackDb')
+
+        when: "the initializer is configured"
+        def applicationContext = initializer.configure()
+        def mongoDatastore = applicationContext.getBean(MongoDatastore)
+
+        then: "the fallback database name is used"
+        mongoDatastore.getDefaultDatabase() == 'fallbackDb'
+
+        cleanup:
+        mongoDatastore.destroy()
+    }
+
+    void "Test setDatabaseName is ignored when grails.mongodb.databaseName is 
explicitly configured"() {
+        given: "an initializer with both a customized database name and an 
explicit database name config"
+        def initializer = makeInitializer([
+                (MongoSettings.SETTING_DATABASE_NAME): 'explicit',
+                (MongoSettings.SETTING_HOST)         : mongoHost,
+                (MongoSettings.SETTING_PORT)         : mongoPort,
+        ], Person)
+        initializer.setDatabaseName('fallbackDb')
+
+        when: "the initializer is configured"
+        def applicationContext = initializer.configure()
+        def mongoDatastore = applicationContext.getBean(MongoDatastore)
+
+        then: "the explicit configuration wins over the fallback"
+        mongoDatastore.getDefaultDatabase() == 'explicit'
+
+        cleanup:
+        mongoDatastore.destroy()
+    }
+
     void "Test that MongoDbDatastoreSpringInitializer can setup GORM for 
MongoDB from scratch"() {
         when: "the initializer used to setup GORM for MongoDB"
         def initializer = makeInitializer([
diff --git 
a/grails-data-mongodb/core/src/test/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializerUnitSpec.groovy
 
b/grails-data-mongodb/core/src/test/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializerUnitSpec.groovy
index c708ac5c4e..3a8c694ec3 100644
--- 
a/grails-data-mongodb/core/src/test/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializerUnitSpec.groovy
+++ 
b/grails-data-mongodb/core/src/test/groovy/grails/mongodb/bootstrap/MongoDbDataStoreSpringInitializerUnitSpec.groovy
@@ -21,6 +21,8 @@ package grails.mongodb.bootstrap
 import com.mongodb.MongoClientSettings
 import com.mongodb.client.MongoClient
 import grails.mongodb.MongoEntity
+import org.grails.datastore.mapping.mongo.config.MongoSettings
+import org.springframework.core.env.PropertyResolver
 import spock.lang.Specification
 
 /**
@@ -109,6 +111,126 @@ class MongoDbDataStoreSpringInitializerUnitSpec extends 
Specification {
         then:
         initializer.mongo.is(client)
     }
+
+    void 'applyDatabaseNameFallback does nothing when the database name was 
never customized'() {
+        given:
+        def initializer = new MongoDbDataStoreSpringInitializer()
+
+        expect:
+        
!initializer.configuration.containsProperty(MongoSettings.SETTING_DATABASE_NAME)
+
+        when:
+        initializer.applyDatabaseNameFallback()
+
+        then:
+        
!initializer.configuration.containsProperty(MongoSettings.SETTING_DATABASE_NAME)
+    }
+
+    void 'applyDatabaseNameFallback injects the customized database name into 
a ConfigurableEnvironment when not already set'() {
+        given:
+        def initializer = new MongoDbDataStoreSpringInitializer()
+        initializer.setDatabaseName('customDb')
+
+        when:
+        initializer.applyDatabaseNameFallback()
+
+        then:
+        
initializer.configuration.getProperty(MongoSettings.SETTING_DATABASE_NAME) == 
'customDb'
+    }
+
+    void 'applyDatabaseNameFallback does not override an already-configured 
database name on a ConfigurableEnvironment'() {
+        given:
+        def initializer = new MongoDbDataStoreSpringInitializer()
+        initializer.configuration.propertySources.addFirst(
+                new org.springframework.core.env.MapPropertySource('test', 
[(MongoSettings.SETTING_DATABASE_NAME): 'explicit']))
+        initializer.setDatabaseName('customDb')
+
+        when:
+        initializer.applyDatabaseNameFallback()
+
+        then:
+        
initializer.configuration.getProperty(MongoSettings.SETTING_DATABASE_NAME) == 
'explicit'
+    }
+
+    void 'applyDatabaseNameFallback injects the customized database name into 
a Map-based PropertyResolver when not already set'() {
+        given:
+        def initializer = new MongoDbDataStoreSpringInitializer()
+        def config = new MapPropertyResolver()
+        initializer.configuration = config
+        initializer.setDatabaseName('customDb')
+
+        when:
+        initializer.applyDatabaseNameFallback()
+
+        then:
+        config.get(MongoSettings.SETTING_DATABASE_NAME) == 'customDb'
+    }
+
+    void 'applyDatabaseNameFallback does not override an already-configured 
database name on a Map-based PropertyResolver'() {
+        given:
+        def initializer = new MongoDbDataStoreSpringInitializer()
+        def config = new 
MapPropertyResolver((MongoSettings.SETTING_DATABASE_NAME): 'explicit')
+        initializer.configuration = config
+        initializer.setDatabaseName('customDb')
+
+        when:
+        initializer.applyDatabaseNameFallback()
+
+        then:
+        config.get(MongoSettings.SETTING_DATABASE_NAME) == 'explicit'
+    }
+}
+
+/**
+ * Minimal {@link PropertyResolver} backed directly by a {@link Map}, standing 
in for
+ * Grails' own {@code Config} type (which is both a {@code Map} and a {@code 
PropertyResolver})
+ * without requiring a dependency on grails-core, which this module 
deliberately excludes.
+ */
+class MapPropertyResolver extends LinkedHashMap<String, Object> implements 
PropertyResolver {
+
+    boolean containsProperty(String key) {
+        containsKey(key)
+    }
+
+    @Override
+    String getProperty(String key) {
+        get(key) as String
+    }
+
+    @Override
+    String getProperty(String key, String defaultValue) {
+        containsKey(key) ? get(key) as String : defaultValue
+    }
+
+    @Override
+    def <T> T getProperty(String key, Class<T> targetType) {
+        get(key) as T
+    }
+
+    @Override
+    def <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
+        containsKey(key) ? get(key) as T : defaultValue
+    }
+
+    @Override
+    String getRequiredProperty(String key) {
+        get(key) as String
+    }
+
+    @Override
+    def <T> T getRequiredProperty(String key, Class<T> targetType) {
+        get(key) as T
+    }
+
+    @Override
+    String resolvePlaceholders(String text) {
+        text
+    }
+
+    @Override
+    String resolveRequiredPlaceholders(String text) {
+        text
+    }
 }
 
 class MappedThing implements MongoEntity<MappedThing> {

Reply via email to