I just fought with this for a while and figured I’d record this in the vast internets in case others come across this. While attempting to extend the functionality of our Grails project at work I needed to add a new table and related foreign key constraints. We use the Grails Database Migration Plugin which uses liquibase to keep our schema in sync between production, staging, and development boxes. I declared a foreign key constraint similar to this one:
addForeignKeyConstraint( | |
baseColumnNames: 'column_name, | |
baseTableSchemaName: 'my_schema', | |
baseTableName: 'my_table', | |
constraintName: 'my_constraint_name', | |
deferrable: 'false', | |
initiallyDeferred: 'false', | |
onDelete: 'CASCADE', | |
onUpdate: 'CASCADE', | |
referencedTableName: 'referenced_table', | |
referencedColumnNames: 'my_referenced_column', | |
referencedTableSchemaName: 'my_schema', | |
referencesUniqueColumn: 'true', | |
) |
and got this exception:
2012-01-25 15:53:13,963 [Thread-12] ERROR context.GrailsContextLoader - Error executing bootstraps: liquibase.exception.ValidationFailedException: Validation Failed: | |
1 changes have validation errors | |
java.lang.ClassCastException: liquibase.statement.core.AddForeignKeyConstraintStatement cannot be cast to liquibase.statement.core.CreateTableStatement | |
org.codehaus.groovy.runtime.InvokerInvocationException: liquibase.exception.ValidationFailedException: Validation Failed: | |
1 changes have validation errors | |
java.lang.ClassCastException: liquibase.statement.core.AddForeignKeyConstraintStatement cannot be cast to liquibase.statement.core.CreateTableStatement | |
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:97) | |
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) | |
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272) | |
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:884) | |
at groovy.lang.Closure.call(Closure.java:410) | |
at DatabaseMigrationGrailsPlugin$_closure2.call(DatabaseMigrationGrailsPlugin.groovy) | |
at org.codehaus.groovy.grails.plugins.DefaultGrailsPlugin.doWithApplicationContext(DefaultGrailsPlugin.java:489) | |
at org.codehaus.groovy.grails.plugins.AbstractGrailsPluginManager.doPostProcessing(AbstractGrailsPluginManager.java:169) | |
at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.performPostProcessing(GrailsRuntimeConfigurator.java:232) | |
at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:172) | |
at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:124) | |
at org.codehaus.groovy.grails.web.context.GrailsConfigUtils.configureWebApplicationContext(GrailsConfigUtils.java:121) | |
at org.codehaus.groovy.grails.web.context.GrailsContextLoader.initWebApplicationContext(GrailsContextLoader.java:104) | |
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) | |
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723) | |
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226) | |
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221) | |
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) | |
at java.util.concurrent.FutureTask.run(FutureTask.java:138) | |
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) | |
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) | |
at java.lang.Thread.run(Thread.java:680) | |
Caused by: liquibase.exception.ValidationFailedException: Validation Failed: | |
1 changes have validation errors | |
java.lang.ClassCastException: liquibase.statement.core.AddForeignKeyConstraintStatement cannot be cast to liquibase.statement.core.CreateTableStatement | |
at liquibase.changelog.DatabaseChangeLog.validate(DatabaseChangeLog.java:138) | |
at liquibase.Liquibase.update(Liquibase.java:110) | |
at liquibase.Liquibase$update.call(Unknown Source) | |
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) | |
at grails.plugin.databasemigration.MigrationRunner$_autoRun_closure1.doCall(MigrationRunner.groovy:50) | |
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) | |
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) | |
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) | |
at java.lang.reflect.Method.invoke(Method.java:597) | |
at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231) | |
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:226) | |
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:52) | |
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141) | |
at grails.plugin.databasemigration.MigrationRunner$_autoRun_closure1.doCall(MigrationRunner.groovy) | |
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) | |
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) | |
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) | |
at java.lang.reflect.Method.invoke(Method.java:597) | |
at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231) | |
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) | |
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) | |
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1054) | |
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110) | |
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:884) | |
at groovy.lang.Closure.call(Closure.java:410) | |
at grails.plugin.databasemigration.MigrationRunner$_autoRun_closure1.call(MigrationRunner.groovy) | |
at groovy.lang.Closure.call(Closure.java:404) | |
at grails.plugin.databasemigration.MigrationRunner$_autoRun_closure1.call(MigrationRunner.groovy) | |
at java_util_concurrent_Callable$call.call(Unknown Source) | |
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112) | |
at grails.plugin.databasemigration.MigrationUtils.executeInSession(MigrationUtils.groovy:99) | |
at grails.plugin.databasemigration.MigrationUtils$executeInSession.call(Unknown Source) | |
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) | |
at grails.plugin.databasemigration.MigrationRunner.autoRun(MigrationRunner.groovy:46) | |
at grails.plugin.databasemigration.MigrationRunner$autoRun.call(Unknown Source) | |
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) | |
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112) | |
at DatabaseMigrationGrailsPlugin$_closure2.doCall(DatabaseMigrationGrailsPlugin.groovy:84) | |
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) | |
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) | |
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) | |
at java.lang.reflect.Method.invoke(Method.java:597) | |
at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231) | |
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) | |
... 21 more |
It turns out that passing in a named parameter of referencesUniqueColumn with a value of anything other than false causes this exception. This wasn’t immediately obvious to me and I still don’t know why, but I thought I’d note it in case someone else ran into it too.