apache / apache/grails-core

Dynamic associations are not loaded correctly when they have instance level labels

Open
#14,619 27 comments 0 reactions 0 assignees View on GitHub
relates-to: gorm relates-to: grails-data-graphql
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

We have the following classes:
```
class Player extends AbstractGraphDomain {

String name

static mapping = {
dynamicAssociations true
labels "__Player__", { GraphPersistentEntity pe, Player instance ->
"Player__${instance.name}"
}
}

}

class Club extends AbstractGraphDomain {

String name

static mapping = {
dynamicAssociations true
labels "__Club__", { GraphPersistentEntity pe, Club instance ->
"Club__${instance.name}"
}
}

}
```

We set a dynamic property called "club" to a player object. Then when we try to access that property we are getting the following exception:

```
org.grails.datastore.mapping.engine.NonPersistentTypeException: [__Club__, Club__club1]
at org.grails.datastore.gorm.neo4j.engine.DynamicAssociationSupport.loadDynamicAssociations(DynamicAssociationSupport.java:91)
at grails.neo4j.Neo4jEntity$Trait$Helper$_getAt_closure1.doCall(Neo4jEntity.groovy:83)
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:1027)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at org.grails.datastore.gorm.GormStaticApi$_withSession_closure21.doCall(GormStaticApi.groovy:811)
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:1027)
at groovy.lang.Closure.call(Closure.java:414)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
at com.sun.proxy.$Proxy102.doInSession(Unknown Source)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:319)
at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:40)
at org.grails.datastore.gorm.GormStaticApi.withSession(GormStaticApi.groovy:810)
at grails.neo4j.Neo4jEntity$Trait$Helper.getAt(Neo4jEntity.groovy:82)
at grails.neo4j.Neo4jEntity$Trait$Helper$getAt$0.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 core.Player.getAt(Player.groovy)
at grails.neo4j.Neo4jEntity$Trait$Helper.propertyMissing(Neo4jEntity.groovy:54)
at grails.neo4j.Neo4jEntity$Trait$Helper$propertyMissing.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 core.Player.propertyMissing(Player.groovy)
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.MetaClassImpl.invokeMissingProperty(MetaClassImpl.java:883)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1864)
at groovy.lang.ExpandoMetaClass.getProperty(ExpandoMetaClass.java:1155)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3763)
at groovy.lang.ExpandoMetaClass.getProperty(ExpandoMetaClass.java:1167)
at core.AbstractGraphDomain.getProperty(AbstractGraphDomain.groovy)
at core.Player.getProperty(Player.groovy)
at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:50)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:307)
at core.InitializeService.$tt__initialize(InitializeService.groovy:20)
at core.InitializeService$_initialize_closure1.doCall(InitializeService.groovy)
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:1027)
at groovy.lang.Closure.call(Closure.java:414)
at core.InitializeService$_initialize_closure1.call(InitializeService.groovy)
at groovy.lang.Closure.call(Closure.java:430)
at core.InitializeService$_initialize_closure1.call(InitializeService.groovy)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
at core.InitializeService.initialize(InitializeService.groovy)
at core.InitializeService$initialize.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:117)
at sampleapp2.BootStrap.initialize(BootStrap.groovy:14)
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)
```

You can reproduce that by running the project in https://github.com/mburak/sampleapp

Contributor guide

Open the contributing guide

Research direction

Reproduce the failure using the sample project at github.com/mburak/sampleapp, then inspect DynamicAssociationSupport.java at the failing loadDynamicAssociations call and Neo4jEntity.groovy around getAt. Compare the dynamic association lookup with the instance-level labels shown in the issue. Done means accessing the dynamic club association no longer raises NonPersistentTypeException.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy, neo4j
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.