2017-02-09 77 views
1

我試圖將我的Grails應用程序從3.1.10升級到3.2.5,以使用新的GORM等,但啓動到達數據庫遷移時失敗。將Grails應用程序從3.1.10升級到3.2.5時出錯

我得到:

INFO 2/9/17 2:08 PM: liquibase: Can not use class org.grails.plugins.databasemigration.liquibase.GormDatabase as a Liquibase service because it does not have a no-argument constructor 
ERROR org.springframework.boot.SpringApplication - Application startup failed 
org.springframework.transaction.HeuristicCompletionException: Heuristic completion: outcome state is rolled back; nested exception is org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction 
at org.grails.transaction.ChainedTransactionManager.commit(ChainedTransactionManager.java:183) 
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:150) 
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93) 
at grails.transaction.GrailsTransactionTemplate$execute.call(Unknown Source) 
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) 
at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager.withTransaction(DatabaseMigrationTransactionManager.groovy:31) 
at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager$withTransaction.call(Unknown Source) 
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) 
at org.grails.plugins.databasemigration.DatabaseMigrationGrailsPlugin$_doWithApplicationContext_closure2.doCall(DatabaseMigrationGrailsPlugin.groovy:77) 
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:497) 
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426) 
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) 
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) 
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294) 
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024) 
at groovy.lang.Closure.call(Closure.java:414) 
at groovy.lang.Closure.call(Closure.java:430) 
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2030) 
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2015) 
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2068) 
at org.codehaus.groovy.runtime.dgm$164.invoke(Unknown Source) 
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274) 
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56) 
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) 
at org.grails.plugins.databasemigration.DatabaseMigrationGrailsPlugin.doWithApplicationContext(DatabaseMigrationGrailsPlugin.groovy:63) 
at org.grails.plugins.DefaultGrailsPlugin.doWithApplicationContext(DefaultGrailsPlugin.java:523) 
at org.grails.plugins.AbstractGrailsPluginManager.doPostProcessing(AbstractGrailsPluginManager.java:224) 
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:246) 
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy) 
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167) 
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) 
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383) 
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337) 
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:882) 
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545) 
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) 
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) 
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:372) 
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:83) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:388) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:375) 
at grails.boot.GrailsApp$run.call(Unknown Source) 
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) 
at saasapi.Application.main(Application.groovy:8) 
Caused by: org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:704) 
at org.grails.transaction.MultiTransactionStatus.commit(MultiTransactionStatus.java:73) 
at org.grails.transaction.ChainedTransactionManager.commit(ChainedTransactionManager.java:156) 
... 56 common frames omitted 

我已經更新或添加到我的build.gradle以下依存關係:

buildscript { 
    ... 
    dependencies { 
     .... 
     classpath "org.grails.plugins:hibernate5:6.0.4" 
     classpath 'org.grails.plugins:database-migration:3.0.0' 
    } 
} 

dependencies { 
    ... 
    runtime 'mysql:mysql-connector-java:5.1.40' 
    compile "org.grails.plugins:hibernate5" 
    compile "org.hibernate:hibernate-core:5.1.1.Final" 
    compile "org.hibernate:hibernate-ehcache:5.1.1.Final" 
    runtime 'org.grails.plugins:database-migration:3.0.0' 
    compile 'org.liquibase:liquibase-core:3.5.3' 
    compile 'org.grails.plugins:mongodb' 
} 

人們看到liquibase錯誤「PM:liquibase:不能使用類組織.grails.plugins.databasemigration.liquibase.GormDatabase作爲Liquibase服務,因爲它沒有無參數的構造函數「以前在這些Github問題中:

https://github.com/grails-plugins/grails-database-migration/issues/81

https://github.com/grails-plugins/grails-database-migration/issues/64#issuecomment-256739113

但對於他們來說,這不是一個破錯誤。

當我嘗試更新到Grails 3.2.3時,我也看到了liquibase錯誤消息,但其他所有工作都一樣(遷移日誌也不可見)。也許問題出在那裏,Grails 3.2.3使用Spring Boot 1.4.1,但Grails 3.2.5使用Spring Boot 1.4.4。

反正我迷路了,我希望有人能幫助我。

編輯:我用數據庫遷移插件來設置我的數據庫表,我現在也用它來改變它。此外,我還啓用了啓動時的數據庫遷移。

EDIT2:看來這個問題本身是沒有這麼多相關的數據庫遷移

我使用多個數據源(相關部分從application.yml):

hibernate: 
    cache: 
     queries: false 
     use_second_level_cache: true 
     use_query_cache: false 
     region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory 

dataSources: 
    dataSource: 
     pooled: true 
     jmxExport: true 
     driverClassName: com.mysql.jdbc.Driver 
     dialect: org.hibernate.dialect.MySQL5InnoDBDialect 
     dbCreate: none 
     properties: 
      testOnBorrow: true 
      validationQuery: SELECT 1 
    myOtherDataSource: 
     pooled: true 
     jmxExport: true 
     driverClassName: net.sourceforge.jtds.jdbc.Driver 
     dialect: org.hibernate.dialect.SQLServerDialect 
     dbCreate: none 

environments: 
    development: 
     dataSources: 
      dataSource: 
       url: jdbc:mysql://localhost/my_default_db?useUnicode=yes&characterEncoding=UTF-8&autoReconnect=true 
       username: my_user 
       password: my_pass 
      myOtherDataSource: 
       driverClassName: com.mysql.jdbc.Driver 
       dialect: org.hibernate.dialect.MySQL5InnoDBDialect 
       url: jdbc:mysql://localhost/my_other_db?useUnicode=yes&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&maxReconnects=10 
       username: my_user 
       password: my_pass 

而且我可以開始我的應用程序,當啓動時沒有數據庫遷移,但隨後我得到與db相關的不同錯誤:

ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - PooledConnection has already been closed. 
ERROR org.grails.web.errors.GrailsExceptionResolver - SQLException occurred when processing request: [GET] /my-endpoint 
...... 
Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement 
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) 
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) 
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:182) 
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148) 
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1934) 
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1903) 
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1881) 
at org.hibernate.loader.Loader.doQuery(Loader.java:925) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342) 
at org.hibernate.loader.Loader.doList(Loader.java:2622) 
at org.hibernate.loader.Loader.doList(Loader.java:2605) 
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2434) 
at org.hibernate.loader.Loader.list(Loader.java:2429) 
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:109) 
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1787) 
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:363) 
at org.grails.orm.hibernate.query.AbstractHibernateQuery.listForCriteria(AbstractHibernateQuery.java:700) 
at org.grails.orm.hibernate.query.AbstractHibernateQuery.list(AbstractHibernateQuery.java:690) 
at org.grails.datastore.gorm.finders.FindAllByFinder.invokeQuery(FindAllByFinder.java:54) 
at org.grails.datastore.gorm.finders.FindAllByFinder$1.doInSession(FindAllByFinder.java:48) 
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:318) 
at org.grails.datastore.gorm.finders.AbstractFinder.execute(AbstractFinder.java:42) 
at org.grails.datastore.gorm.finders.FindAllByFinder.doInvokeInternal(FindAllByFinder.java:45) 
at org.grails.datastore.gorm.finders.DynamicFinder.invoke(DynamicFinder.java:174) 
at org.grails.datastore.gorm.finders.DynamicFinder.invoke(DynamicFinder.java:374) 
at org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2.doCall(GormStaticApi.groovy:169) 
..... 
Caused by: java.sql.SQLException: PooledConnection has already been closed. 
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.invoke(LazyConnectionDataSourceProxy.java:376) 
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240) 
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240) 
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146) 
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172) 
... 66 common frames omitted 

回答

0

我創建了一個問題,對於這一點,有一個示例應用程序重現此行爲:https://github.com/grails/grails-core/issues/10477

[更新]:

我終於想通了。 Grails將爲數據源下的每個配置創建一個平臺事務管理器,併爲默認數據源創建一個。在你的例子中,這看起來像[dataSource,myOtherDataSource,dataSource]。這顯然不是應該發生的事情。在GORM文件中指定您應該使用:

dataSource: 
    .. 
dataSources: 
    myOtherDataSource: 

這將行得通。 Grails創建兩個平臺事務管理器,這是正確的行爲。

但Databasemigration期望所有數據源都在dataSources配置塊中,因此它無法找到默認數據源。 我爲此創建了一個修補程序,只要修復了其他相關的bug,就會爲此創建一個pullrequest;

Grails不會在Multi DataSource配置的applicationContext中使用名稱'dataSource'發佈默認的DataSource。 我已經添加到了這個問題https://github.com/grails/grails-core/issues/10477

[更新2]:

我已經創建了兩個引入請求來解決這個問題:

的Grails,插件/ Grails的數據庫遷移/拉/ 123

的grails/Grails的核/拉/ 10478

這些解決了我的系統上的問題。我無法發佈兩個鏈接,因爲我沒有足夠的聲譽根據計算器:S

+0

我知道Stack Overflow建議不要在評論中感謝,但仍然感謝您創建該問題。 – siimval

0

我有幾乎相同的設置,因爲你有我沒有問題。我有最顯着的變化是我使用5.1.3最終的hibernate-core和ehcache和org.grails.plugins:hibernate5:6.0.6。我沒有mongodb依賴。

  • 你有多個數據源嗎?
  • 它是否在沒有運行任何遷移文件的情況下啓動?
+0

是的,我有多個不同的數據源。但只有一個用於數據庫遷移。我將在我的原始文章中提供我的application.yml中的相關部分。 是的,它啓動時不運行遷移文件。但後來我得到了與db連接有關的各種不同的錯誤。我將在原始文章中提供來自錯誤堆棧跟蹤的有意義的示例行。 – siimval

0

我有幾乎與Grails-3.2.5/3.2.6相同的問題。 請嘗試Grails-3.2.4並查看問題是否仍然存在。

0

使用多個數據源我有同樣的問題。它只發生在默認的Datasource上,它看起來像GrailsTemplate,它試圖恢復以前的狀態並且不這樣做,因爲事務被提交。

org.springframework.transaction.HeuristicCompletionException: Heuristic completion: outcome state is rolled back; nested exception is org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction 
    at org.grails.transaction.ChainedTransactionManager.commit(ChainedTransactionManager.java:183) 
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:150) 
    at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93) 
    at grails.transaction.GrailsTransactionTemplate$execute.call(Unknown Source) 
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) 
    at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager.withTransaction(DatabaseMigrationTransactionManager.groovy:31) 
    at org.grails.plugins.databasemigration.DatabaseMigrationTransactionManager$withTransaction.call(Unknown Source) 
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) 
    at org.grails.plugins.databasemigration.DatabaseMigrationGrailsPlugin$_doWithApplicationContext_closure2.doCall(DatabaseMigrationGrailsPlugin.groovy:77) 
    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:497) 
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426) 
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) 
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) 
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294) 
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024) 
    at groovy.lang.Closure.call(Closure.java:414) 
    at groovy.lang.Closure.call(Closure.java:430) 
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2030) 
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2015) 
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2068) 
    at org.codehaus.groovy.runtime.dgm$164.invoke(Unknown Source) 
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274) 
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56) 
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) 
    at org.grails.plugins.databasemigration.DatabaseMigrationGrailsPlugin.doWithApplicationContext(DatabaseMigrationGrailsPlugin.groovy:63) 
    at org.grails.plugins.DefaultGrailsPlugin.doWithApplicationContext(DefaultGrailsPlugin.java:523) 
    at org.grails.plugins.AbstractGrailsPluginManager.doPostProcessing(AbstractGrailsPluginManager.java:224) 
    at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:246) 
    at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy) 
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167) 
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) 
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383) 
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337) 
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:882) 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545) 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) 
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:372) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) 
    at grails.boot.GrailsApp.run(GrailsApp.groovy:83) 
    at grails.boot.GrailsApp.run(GrailsApp.groovy:388) 
    at grails.boot.GrailsApp.run(GrailsApp.groovy:375) 
    at grails.boot.GrailsApp$run.call(Unknown Source) 
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) 
    at scd.Application.main(Application.groovy:8) 
    Caused by: org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:704) 
    at org.grails.transaction.MultiTransactionStatus.commit(MultiTransactionStatus.java:73) 
    at org.grails.transaction.ChainedTransactionManager.commit(ChainedTransactionManager.java:156) 
    ... 56 common frames omitted 
+0

我做了一個沒有失敗的小測試用例。在從原始項目複製到我的域類後,它再次失敗。經過一些試驗和錯誤後,我發現如果您有32個或更多的域類,就會發生這個錯誤。 –

相關問題