grails-data-mapping
grails-data-mapping copied to clipboard
Grails 3.3.9: Unable to inherit hasMany property
I'm currently migrating my grails code from version 2.5.6 to 3.3.9. On 3.3.9, I observed this weird behaviour.
There's an abstract class (in src/main/groovy) which contains a hasMany relationship.
package srcFolder
import grailsthree.TestSimpleClass
abstract class TestSuperClass {
String superClassValue
static hasMany = [simples: TestSimpleClass]
}
A domain class which inherits this abstract class.
package grailsthree
import srcFolder.TestSuperClass
class TestSubClass extends TestSuperClass{
String subClassValue
static constraints = {
}
}
In the Bootstrap, call the addTo on the hasMany property of subclass,
package grailsthree
class BootStrap {
def init = { servletContext ->
TestSimpleClass testSimpleClass = new TestSimpleClass(simpleClassValue: 'simpleClassValue').save()
TestSubClass testSubClass = new TestSubClass(subClassValue: 'subClassValue')
testSubClass.addToSimples(testSimpleClass)
testSubClass.save()
}
def destroy = {
}
}
Got following error:
groovy.lang.MissingMethodException: No signature of method: grailsthree.TestSubClass.addToSimples() is applicable for argument types: (grailsthree.TestSimpleClass) values: [grailsthree.TestSimpleClass : 1]
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:71)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:53)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
at grailsthree.BootStrap$_closure1.doCall(BootStrap.groovy:8)
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.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1099)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
at groovy.lang.Closure.call(Closure.java:418)
at groovy.lang.Closure.call(Closure.java:412)
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:541)
at grails.util.Environment.executeForEnvironment(Environment.java:534)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:510)
at org.grails.web.servlet.boostrap.DefaultGrailsBootstrapClass.callInit(DefaultGrailsBootstrapClass.java:74)
at org.grails.web.servlet.context.GrailsConfigUtils.executeGrailsBootstraps(GrailsConfigUtils.java:65)
at org.grails.plugins.web.servlet.context.BootStrapClassRunner.onStartup(BootStrapClassRunner.groovy:53)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:263)
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:393)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:146)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:124)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at grails.boot.GrailsApp.run(GrailsApp.groovy:84)
at grails.boot.GrailsApp.run(GrailsApp.groovy:393)
at grails.boot.GrailsApp.run(GrailsApp.groovy:380)
at grails.boot.GrailsApp$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
at grailsthree.Application.main(Application.groovy:8)
Seems like on Grails 3.3.9, the sub-class is not inheriting the abstract class hasMany property. This is working fine for Grails 2.5.6.
Expected Behaviour
The child sub-domain class should've inherited the hasMany relationship from the abstract class.
Actual Behaviour
The child sub-domain class doesn't inherit the hasMany relationship from the abstract class.
Environment Information
- Operating System: Ubuntu 16.04
- Grails Version: 3.3.9
- JDK Version: 1.8.0_201
As a workaround, I've converted the above-mentioned src/main/groovy classes into domain classes, and I've added static mapWith block set to "none" to make sure they're not persistable.