Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mburak opened this issue Apr 12, 2017 · 27 comments

Comments

@mburak
Copy link
Contributor

mburak commented Apr 12, 2017

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

@graemerocher
Copy link
Member

This is the challenge with dynamic labels and dynamic associations (both features that should not exist IMO as the former prevents batch updates/optimized writes and the latter has a negative impact on read performance ).

Since we cannot know for sure what domain class type the labels are associated with we cannot establish the inverse type of the association (in this case Club). I see no way to fix this as it stands.

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017 via email

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017 via email

@graemerocher
Copy link
Member

Not possible, how would you know the static labels? Given that you have no idea what is the inverse entity of the association

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017 via email

@graemerocher
Copy link
Member

As far as I can see targetType is already used to try to establish the entity as a fallback:

https://github.com/grails/gorm-neo4j/blob/master/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/DynamicAssociationSupport.java#L87

So that points to a likely a data corruption problem

@graemerocher
Copy link
Member

I ran the application at https://github.com/mburak/sampleapp and no exception was thrown

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017

Hm you are in master? I just ran it again and it threw it.
If you look at the sample I provided, it doesn't seem to be a data corruption issue because it's just creating the data on startup and throwing the exception right away.

I think the issue is that you are using the labels instead of the target type here:
https://github.com/grails/gorm-neo4j/blob/master/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/DynamicAssociationSupport.java#L73

But in the entitiesByLabel you are storing only the static label as key:

image

@graemerocher
Copy link
Member

Application runs fine for me on master

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017

Please update the code and try again.

@graemerocher
Copy link
Member

I noticed it printed Player's club is null so it was probably down to the dynamic labels causing issues again. Removing them, dropping the data and re-running the app produces this output:

2017-04-20 17:16:10.455 DEBUG --- [           main] o.g.datastore.gorm.neo4j.Neo4jDatastore  : Setting up indexing for entity org.sampleapp.core.Application
2017-04-20 17:16:10.459 DEBUG --- [           main] o.g.datastore.gorm.neo4j.Neo4jDatastore  : Setting up indexing for entity org.sampleapp.core.Player
2017-04-20 17:16:10.459 DEBUG --- [           main] o.g.datastore.gorm.neo4j.Neo4jDatastore  : Setting up indexing for entity org.sampleapp.core.AbstractGraphDomain
2017-04-20 17:16:10.459 DEBUG --- [           main] o.g.datastore.gorm.neo4j.Neo4jDatastore  : Setting up indexing for entity org.sampleapp.core.Club
2017-04-20 17:16:10.584 DEBUG --- [           main] o.g.datastore.gorm.neo4j.Neo4jDatastore  : done setting up indexes
2017-04-20 17:16:14.731 DEBUG --- [           main] o.g.datastore.gorm.neo4j.Neo4jSession    : Session created
2017-04-20 17:16:14.842 DEBUG --- [           main] g.d.g.n.Neo4jDatastoreTransactionManager : Found thread-bound Session [org.grails.datastore.gorm.neo4j.Neo4jSession@14d36bb2] for Datastore transaction
2017-04-20 17:16:14.842 DEBUG --- [           main] g.d.g.n.Neo4jDatastoreTransactionManager : Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2017-04-20 17:16:14.846 DEBUG --- [           main] o.g.d.gorm.neo4j.Neo4jTransaction        : TX START: Neo4J beginTx()
2017-04-20 17:16:15.332 DEBUG --- [           main] o.g.d.g.n.engine.Neo4jEntityPersister    : CREATE Cypher [CREATE (n:Application {props}) RETURN ID(n) as id] for parameters [{props={name=app1, lastUpdated=1492701375327, appVersion=1, dateCreated=1492701375327, version=0}}]
2017-04-20 17:16:15.355 DEBUG --- [           main] o.g.d.g.n.engine.Neo4jEntityPersister    : CREATE Cypher [CREATE (n:__Club__ {props}) RETURN ID(n) as id] for parameters [{props={name=club1, lastUpdated=1492701375355, dateCreated=1492701375355, version=0}}]
2017-04-20 17:16:15.370 DEBUG --- [           main] o.g.d.g.n.engine.Neo4jEntityPersister    : CREATE Cypher [CREATE (n:__Player__ {props}) RETURN ID(n) as id] for parameters [{props={name=player1, lastUpdated=1492701375367, dateCreated=1492701375367, version=0}}]
2017-04-20 17:16:15.391 DEBUG --- [           main] o.g.d.g.n.e.RelationshipPendingInsert    : MERGE Cypher [MATCH (from:__Player__),(to:__Club__) WHERE ID(from) = {start} AND ID(to) IN {end} MERGE (from)-[r:club{sourceType:'Player',targetType:'Club'}]->(to)] for parameters [{start=530, end=[529]}]
2017-04-20 17:16:15.393 DEBUG --- [           main] o.g.d.g.n.e.RelationshipPendingInsert    : MERGE Cypher [MATCH (from:__Player__),(to:__Club__) WHERE ID(from) = {start} AND ID(to) IN {end} MERGE (from)-[r:club{sourceType:'Player',targetType:'Club'}]->(to)] for parameters [{start=530, end=[529]}]
2017-04-20 17:16:15.544 DEBUG --- [           main] o.g.d.gorm.neo4j.engine.Neo4jQuery       : QUERY Cypher [MATCH (n:__Player__) WHERE ( n.name={1} ) RETURN n as data
 
] for params [[1:player1]]
2017-04-20 17:16:15.560 DEBUG --- [           main] o.g.d.g.n.engine.Neo4jEntityPersister    : unmarshalling entity [org.sampleapp.core.Player] with id [530], props node<530>, {}
2017-04-20 17:16:15.570 DEBUG --- [           main] o.g.d.g.n.e.DynamicAssociationSupport    : QUERY Cypher [MATCH (n:__Player__)-[r]-(o) WHERE ID(n) = {id} RETURN type(r) as relType, startNode(r) = n as out, r.sourceType as sourceType, r.targetType as targetType, {ids: collect(ID(o)), labels: collect(labels(o))} as values] for parameters [{id=530}]
Player's club is org.sampleapp.core.Club : 529
2017-04-20 17:16:15.621 DEBUG --- [           main] g.d.g.n.Neo4jDatastoreTransactionManager : Initiating transaction commit
2017-04-20 17:16:15.621 DEBUG --- [           main] g.d.g.n.Neo4jDatastoreTransactionManager : Flushing Session prior to transaction commit [org.grails.datastore.gorm.neo4j.Neo4jSession@14d36bb2]
2017-04-20 17:16:15.627 DEBUG --- [           main] o.g.d.g.n.e.RelationshipPendingInsert    : DELETE Cypher [MATCH (from:__Player__)-[r:club{sourceType:'Player',targetType:'Club'}]->(to:__Club__) WHERE ID(from) IN {start} DELETE r] for parameters [{start=530}]
2017-04-20 17:16:15.627 DEBUG --- [           main] o.g.d.g.n.e.RelationshipPendingInsert    : MERGE Cypher [MATCH (from:__Player__),(to:__Club__) WHERE ID(from) = {start} AND ID(to) IN {end} MERGE (from)-[r:club{sourceType:'Player',targetType:'Club'}]->(to)] for parameters [{start=530, end=[529]}]
2017-04-20 17:16:15.628 DEBUG --- [           main] g.d.g.n.Neo4jDatastoreTransactionManager : Committing Datastore transaction on Session [org.grails.datastore.gorm.neo4j.Neo4jSession@14d36bb2]
2017-04-20 17:16:15.628 DEBUG --- [           main] o.g.d.gorm.neo4j.Neo4jTransaction        : TX COMMIT: Neo4J success()
2017-04-20 17:16:15.628 DEBUG --- [           main] o.g.d.gorm.neo4j.Neo4jTransaction        : TX CLOSE: Neo4j tx.close()
2017-04-20 17:16:15.663 DEBUG --- [           main] g.d.g.n.Neo4jDatastoreTransactionManager : Resuming suspended transaction after completion of inner transaction
2017-04-20 17:16:15.665 DEBUG --- [           main] o.g.datastore.gorm.neo4j.Neo4jSession    : Session closed
Grails application running at http://localhost:8080 in environment: development

As far as I can see from the output, I can see issue #46 which is fixed already but not much else.

If I restore the dynamic labels then it prints Player's club is null since it doesn't know how to discover them.

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017

This is with the latest code?

@graemerocher
Copy link
Member

Was finally able to reproduce after making several modifications to the code. So this doesn't seem to be a new bug, the same behaviour is present in 6.0.x which is the first version to have supported Neo4j 3.x and Bolt. Downgrading the sample to any version of 6.0.x reproduces the same issue.

As far as I can see there is no way to solve it reliably since targetType is set to Club without a package name. If you had multiple domain classes within the same name targetType cannot be used to resolve the domain class.

IMO It is another example of why you should stay away from both dynamic labels and dynamic associations. You can of course choose to ignore my recommendation, but if you want your applications to perform well and work consistently I recommend you don't use them.

I believe we should in fact deprecate support for them and remove them completely in the future as they are not something we believe should be used by any user going forward.

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017

Ok, It's weird that we are not getting that with older version as we've been using that for a long time and it's working.
I understand that the use of dynamic labels and associations might have certain drawbacks but they are the core of our application and we really need them.

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017

And also, the problem with this is that it's happening with static associations too, so it doesn't matter if it's static or dynamic. If you have a dynamic label, it will throw the exception:
Steps are:
1 - Add a new property to Player

    static hasMany = [formerClubs: Club]

Club has dynamic(instance) labels
2 - Try to get any dynamic property from player. Then this goes throw the propertyMissing and finally DynamicAssociationSupport which is trying to load all the relationships (static and dynamic) and it's not finding the one for formerClubs nodes, throwing this exception:

org.grails.datastore.mapping.engine.NonPersistentTypeException: [__Club__, Club__club3]
        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.$Proxy103.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$1.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$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.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:35)
        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)
        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:384)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:158)
        at sampleapp2.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: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.MetaClassImpl.invokeMethod(MetaClassImpl.java:1092)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
        at groovy.lang.Closure.call(Closure.java:414)
        at groovy.lang.Closure.call(Closure.java:408)
        at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:535)
        at grails.util.Environment.executeForEnvironment(Environment.java:528)
        at grails.util.Environment.executeForCurrentEnvironment(Environment.java:504)
        at org.grails.web.servlet.boostrap.DefaultGrailsBootstrapClass.callInit(DefaultGrailsBootstrapClass.java:62)
        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:256)
        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 sampleapp2.Application.main(Application.groovy:8)

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017

I think that one of the issues is that the query built here:
https://github.com/grails/gorm-neo4j/blob/master/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/DynamicAssociationSupport.java#L42
is getting all the relationships, not only the dynamic ones.

@graemerocher
Copy link
Member

That is also the same as in 6.0.x and probably earlier versions. The query format hasn't changed much for dynamic associations

@mburak
Copy link
Contributor Author

mburak commented Apr 20, 2017

Well but you didn't have the DynamicAssociationSupport and the propertyMissing going through that class and doing those queries.

@graemerocher
Copy link
Member

The code just moved from Neo4jEntityPersister to DynamicAssociationSupport but the query format is the same. Like I said changing the version in the the same app to any version of 6.0.x produces the same issue, so since this is not a regression and I see no way to fix this reliably I don't see anyway to take it forward.

@graemerocher
Copy link
Member

The only change we can possibly make is changing this line:

if(associatedEntity == null) {
       throw new NonPersistentTypeException(labels.toString());
 }

To

if(associatedEntity == null) {
    continue
}

That would at least ignore the exception for other dynamic properties. In terms of establishing which entity the associated relates to, I don't see a way to do that.

@mburak
Copy link
Contributor Author

mburak commented Apr 21, 2017 via email

@graemerocher
Copy link
Member

Agreed it should, but how would you tell which ones where dynamic and which ones were not in the query? Also that behaviour is the same as 6.0.x so that is again not a change or regression in behaviour.

Like I said the query hasn't changed. Just moved. It was here before https://github.com/grails/gorm-neo4j/blob/6.0.x/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/Neo4jEntityPersister.java#L53

Now it is here https://github.com/grails/gorm-neo4j/blob/master/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/GraphPersistentEntity.groovy#L216

@mburak
Copy link
Contributor Author

mburak commented Apr 21, 2017 via email

@graemerocher
Copy link
Member

static associations still don't have sourceType and targetType. They are only included for dynamic associations https://github.com/grails/gorm-neo4j/blob/master/grails-datastore-gorm-neo4j/src/main/groovy/org/grails/datastore/gorm/neo4j/engine/RelationshipPendingInsert.java#L110

Of course if you have data that you have previously inserted via dynamic associations there is nothing we can do about that. You will have to migrate the data manually

@mburak
Copy link
Contributor Author

mburak commented Apr 21, 2017 via email

@graemerocher
Copy link
Member

I suggest since you have the data model in place you work on a solution that solves the issue for you and a submit a pull request. Thanks.

@mburak
Copy link
Contributor Author

mburak commented Apr 21, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants