pinedu1 opened a new issue, #14337: URL: https://github.com/apache/grails-core/issues/14337
Hello! When activating a MULTITENANT (DATABASE) project, where the configuration is as follows: SO: - **Operating System**: Linux Fedora 39 - **Grails Version:** Grails: 6.2.0 - **Plugin Version:** 5.0.0-SNAPSHOT (Downloaded on: 2024-08-12) - **Database:** Postgresql12 - **JDK Version:** openjdk version "17.0.12" 2024-07-16 - ** LINK TO REPOSITORY **: https://github.com/pinedu1/pndImo Where I downloaded the source code from the 5.x branch, compiled it, and distributed it to my local Maven repository: /*code*/ #> ./gradlew publishToMavenLocal -x groovydoc /*code*/ I added this compilation to my project: build.gradle /*code*/ buildscript { dependencies { classpath 'org.grails.plugins:database-migration:5.0.0-SNAPSHOT' } } sourceSets { main { resources { srcDir 'grails-app/migrations' } } } ... dependencies { ... implementation('org.grails.plugins:database-migration:5.0.0-SNAPSHOT') } /*code*/ tenantresolver: org.grails.datastore.mapping.multitenancy.TenantResolver (SUBDOMAIN) application.properties: # Configurações da Aplicação grails.gorm.reactor.events=false grails.gorm.multiTenancy.mode=DATABASE grails.gorm.multiTenancy.tenantResolverClass=org.grails.datastore.mapping.multitenancy.TenantResolver (SUBDOMAIN) grails.plugin.databasemigration.updateAllOnStart=true grails.plugin.databasemigration.updateOnStartFileName=changelog.groovy grails.plugin.databasemigration.changelogFileName=changelog.groovy # Default dataSource.url=jdbc:postgresql://localhost:5432/pnd dataSource.driverClassName=org.postgresql.Driver dataSource.username=pnd dataSource.password=pnd dataSource.pooled=true dataSource.jmxExport=true dataSource.dbCreate=none # Cliente: joao dataSources.JOAO.dbCreate=none dataSources.JOAO.password=joao dataSources.JOAO.url=jdbc:postgresql://localhost:5432/joao dataSources.JOAO.username=joao # Cliente: pedro dataSources.PEDRO.dbCreate=none dataSources.PEDRO.password=pedro dataSources.PEDRO.url=jdbc:postgresql://localhost:5432/pedro dataSources.PEDRO.username=pedro # Cliente: antonio dataSources.ANTONIO.dbCreate=none dataSources.ANTONIO.password=antonio dataSources.ANTONIO.url=jdbc:postgresql://localhost:5432/antonio dataSources.ANTONIO.username=antonio # Cliente: jose dataSources.JOSE.dbCreate=none dataSources.JOSE.password=jose dataSources.JOSE.url=jdbc:postgresql://localhost:5432/jose dataSources.JOSE.username=jose It turns out that in this configuration, the MULTITENANT setup creates the DATASOURCE_NAME map as follows: datasources.JOAO=[map of properties] datasources.PEDRO=[map of properties] ... datasources.ANTONIO=[map of properties] These dataSources are collected by the plugin in: class: DatabaseMigrationGrailsPlugin And in line 100, there is the following method: /* code */ private Set<String> getDataSourceNames() { def dataSources = config.getProperty('dataSources', Map, [:]) if (!dataSources) { return ['dataSource'] } Set<String> dataSourceNames = dataSources.keySet() if (!dataSourceNames.contains('dataSource')) { dataSourceNames = ['dataSource'] + dataSourceNames } return dataSourceNames } /* code */ In this method, the if block: /*code*/ if (!dataSourceNames.contains('dataSource')) { dataSourceNames = ['dataSource'] + dataSourceNames } /*code*/ cannot exist in this configuration, as it creates a false entry in the dataSources set and breaks the UPDATE_ALL_ON_START functionality. In my solution, I simply removed this piece of code (the if condition above). A second point related to my configuration: The class DatabaseMigrationTransactionManager also collects the databases to retrieve the TransactionManager linked to each of these tenants. In line 27 of this class: /*code*/ PlatformTransactionManager getTransactionManager() { String dataSource = this.dataSource ?: "dataSource" String beanName = "transactionManager" if (dataSource != "dataSource") { beanName += "_${dataSource}" } applicationContext.getBean(beanName, PlatformTransactionManager) } /*code*/ The method retrieves the transaction managers, and in my configuration, it retrieves by the object's name: "transactionManager_JOAO" "transactionManager_PEDRO" ... "transactionManager_ANTONIO" However, at some point, the dataSource name becomes degenerated into the following form: "dataSource_JOAO" "dataSource_PEDRO" ... "dataSource_ANTONIO" Where it should simply be: "JOAO" "PEDRO" ... "ANTONIO" My homemade solution was to modify the method as follows: /*code*/ PlatformTransactionManager getTransactionManager() { String dataSource = this.dataSource ?: "dataSource" String beanName = "transactionManager" if (dataSource.startsWith('dataSource_')) { dataSource = dataSource.substring(dataSource.indexOf('_') + 1) } if (dataSource != "dataSource") { beanName += "_${dataSource}" } applicationContext.getBean(beanName, PlatformTransactionManager) } /*code*/ Note that I force the elimination of the 'dataSource_' substring in the following if block: /*code*/ if (dataSource.startsWith('dataSource_')) { dataSource = dataSource.substring(dataSource.indexOf('_') + 1) } /*code*/ -- 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]
