apache / apache/grails-core

Grails 3.3.9: Unable to inherit hasMany property

Open
#14,525 1 comment 0 reactions 0 assignees View on GitHub
info: workaround available relates-to: gorm
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

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

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue with the abstract TestSuperClass in src/main/groovy, TestSubClass, TestSimpleClass, and the BootStrap init code that calls addToSimples. Compare the inherited hasMany behavior in Grails 3.3.9 with the reported Grails 2.5.6 behavior; done means TestSubClass accepts the TestSimpleClass through addToSimples and saves successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.