Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NoSuchBeanDefinitionException for transactionManager bean occurs when using additional dataSource in 3.1.0.RC1 #167

Open
4 tasks done
nobeans opened this issue Mar 2, 2020 · 3 comments

Comments

@nobeans
Copy link

nobeans commented Mar 2, 2020

Task List

  • Steps to reproduce provided
  • Stacktrace (if present) provided
  • Example that reproduces the problem uploaded to Github
  • Full description of the issue provided (see below)

Steps to Reproduce

  1. Define an additional dataSources in application.yml as follows:

    dataSources:
        liquibase:
            url: jdbc:h2:mem:liquibaseDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
            pooled: true
            jmxExport: true
            driverClassName: org.h2.Driver
            username: sa
            password: ''
    
  2. Use the dataSource for grails.plugin.databasemigration.

    grails:
        plugin:
            databasemigration:
                liquibase:
                    updateOnStartFileName: changelog.groovy
                    updateOnStart: true
    
  3. Run grails application.

Expected Behaviour

The application run up normally.

Actual Behaviour

The error occurs:

2020-03-02 13:11:03.195 ERROR --- [  restartedMain] liquibase.changelog.ChangeSet            : Change Set changelog.groovy::test-0001:: failed.  Error: No bean named 'transactionManager_dataSource_liquibase' available
2020-03-02 13:11:03.345 ERROR --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

A component required a bean named 'transactionManager_dataSource_liquibase' that could not be found.


Action:

Consider defining a bean named 'transactionManager_dataSource_liquibase' in your configuration.

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.reflect.UndeclaredThrowableException
        at org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:152)
        at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:807)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:97)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:458)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:445)
        at grails4.issue.Application.main(Application.groovy:11)
        ... 5 more
Caused by: liquibase.exception.MigrationFailedException: Migration failed for change set changelog.groovy::test-0001:::
     Reason: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager_dataSource_liquibase' available
        at liquibase.changelog.ChangeSet.execute(ChangeSet.java:637)
        at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:53)
        at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:83)
        at liquibase.Liquibase.update(Liquibase.java:202)
        at liquibase.Liquibase.update(Liquibase.java:179)
        at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:353)
        at org.grails.plugins.databasemigration.liquibase.GrailsLiquibase.performUpdate(GrailsLiquibase.groovy:83)
        at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:305)
        at org.springframework.beans.factory.InitializingBean$afterPropertiesSet.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:119)
        at org.grails.plugins.databasemigration.DatabaseMigrationGrailsPlugin$_doWithApplicationContext_closure2$_closure5.doCall(DatabaseMigrationGrailsPlugin.groovy:86)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
        at groovy.lang.Closure.call(Closure.java:405)
        at groovy.lang.Closure.call(Closure.java:421)
        at grails.gorm.transactions.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:94)
        at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
        at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:91)
        at grails.gorm.transactions.GrailsTransactionTemplate$execute.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager.withTransaction(DatabaseMigrationTransactionManager.groovy:123)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager$withTransaction$0.callCurrent(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:156)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:176)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager.withTransaction(DatabaseMigrationTransactionManager.groovy:47)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager$withTransaction.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
        at org.grails.plugins.databasemigration.DatabaseMigrationGrailsPlugin$_doWithApplicationContext_closure2.doCall(DatabaseMigrationGrailsPlugin.groovy:75)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
        at groovy.lang.Closure.call(Closure.java:405)
        at groovy.lang.Closure.call(Closure.java:421)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2296)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2281)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2334)
        at org.codehaus.groovy.runtime.dgm$188.invoke(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:244)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
        at org.grails.plugins.databasemigration.DatabaseMigrationGrailsPlugin.doWithApplicationContext(DatabaseMigrationGrailsPlugin.groovy:59)
        at org.grails.plugins.DefaultGrailsPlugin.doWithApplicationContext(DefaultGrailsPlugin.java:507)
        at org.grails.plugins.AbstractGrailsPluginManager.doPostProcessing(AbstractGrailsPluginManager.java:223)
        at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:259)
        at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:896)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
        ... 9 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager_dataSource_liquibase' available
        at io.micronaut.spring.context.factory.MicronautBeanFactory.doGetBean(MicronautBeanFactory.java:730)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:273)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1111)
        at org.springframework.beans.factory.BeanFactory$getBean$1.call(Unknown Source)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager.getTransactionManager(DatabaseMigrationTransactionManager.groovy:33)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.MethodMetaProperty$GetBeanMethodMetaProperty.getProperty(MethodMetaProperty.java:76)
        at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.callGroovyObjectGetProperty(GetEffectivePogoPropertySite.java:68)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager.withTransaction(DatabaseMigrationTransactionManager.groovy:117)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager$withTransaction$0.callCurrent(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:156)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:176)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager.withTransaction(DatabaseMigrationTransactionManager.groovy:107)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager$withTransaction$1.callCurrent(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:156)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:176)
        at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager.withNewTransaction(DatabaseMigrationTransactionManager.groovy:60)
        at org.grails.plugins.databasemigration.liquibase.GroovyChange.withNewTransaction(GroovyChange.groovy:312)
        at org.grails.plugins.databasemigration.liquibase.GroovyChange.generateStatements(GroovyChange.groovy:150)
        at liquibase.change.AbstractChange.generateStatementsVolatile(AbstractChange.java:287)
        at liquibase.changelog.ChangeSet.execute(ChangeSet.java:595)
        ... 85 more

Environment Information

  • Operating System: macOS 10.15.3
  • Grails Version: 4.0.1
  • Plugin Version: 3.1.0.RC1
  • Database: h2
  • JDK Version: 8.0.201-oracle

Example Application

@nobeans
Copy link
Author

nobeans commented Mar 2, 2020

The implementation of GroovyChange seems wrong.

GORM set up beans for each dataSource as follows.

  • for the default dataSource:
    • dataSource
    • transactionManager
  • for the additional dataSource named liquibase:
    • dataSource_liquibase
    • transactionManager_liquibase

The current implementation of GroovyChange uses dataSource bean name as dataSource name. For the default dataSource, the both of them are same, dataSource. But for the additional dataSource which dataSource name is liquibase, the dataSource bean name become dataSource_liquibase internally. This difference makes using wrong transactionManager bean, transactionManager_dataSource_liquibase.

https://github.com/grails-plugins/grails-database-migration/blob/master/src/main/groovy/org/grails/plugins/databasemigration/liquibase/GroovyChange.groovy#L312
https://github.com/grails-plugins/grails-database-migration/blob/master/src/main/groovy/org/grails/plugins/databasemigration/DatabaseMigrationTransactionManager.groovy#L28-L32

To fix it, you get rid of the prefix of dataSource_ of the bean name if its exists.

@nobeans
Copy link
Author

nobeans commented Mar 3, 2020

#157 seems same issue though it's about sessionFactory.

@demus-nine
Copy link

A workaround is to alias the incorrect names to the correct names in spring/resources.groovy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants