spring - NotInTransactionException when adding to mapped set -


i have 2 @nodeentities mapped via sdn using simple mapping, personnode , familynode. familynode has @relatedto collection, children. have familyservice (using spring's @service annotation) @transactional annotation on updatefamily method. method loads familynode given id, , uses callback interface modify node. in 1 implementation of callback, adding personnode children collection, , generating notintransactionexception, @ point neo4j attempting create relationship between familynode , personnode.

source code can found @ github , in particular failing test. here relevant bits of code:

familynode.java:

 @nodeentity  public class familynode implements family {      @indexed(indexname = "families", unique = true)     private string id;     @graphid     private long identifier;     @relatedto(elementclass = personnode.class, type = "child")     private set<person> children;      void addchild(person child) {         if (this.children == null) {         this.children = new hashset<>();         }         this.children.add(child);     } } 

personnode.java:

@nodeentity public class personnode implements person {      @relatedto(elementclass = familynode.class, type = "child", direction = incoming)     private family childof;     @indexed(indexname = "people", unique = true)     private string id;     @graphid     private long identifier; } 

familyrepository.java:

public interface familyrepository extends graphrepository<family> {     public familynode findbyid(string id); } 

familyserviceimpl.java:

@service public class familyserviceimpl implements familyservice {      @autowired     private familyrepository families;     @autowired     private neo4jtemplate template;      @override     public list<family> getfamilies(string[] ids) {         list<family> families = new arraylist<>();         (string id : ids) {             families.add(getfamily(id));         }         return families;     }      @override     public family getfamily(string id) {         return familynode(id);     }      @override     @transactional     public family createfamily(family family) {         return lazyloadrelationships((familynode) this.families.save(family));     }      @override     @transactional     public family updatefamily(string id, familynodeupdater updater) {         return this.families.save(updater.update(familynode(id)));     }      private familynode familynode(string id) {         return lazyloadrelationships(this.families.findbyid(id));     }      private familynode lazyloadrelationships(familynode family) {         this.template.fetch(family.getfather());         this.template.fetch(family.getmother());         this.template.fetch(family.getchildren());         return family;     }  } 

and failing test, familyservicetest.java:

@runwith(springjunit4classrunner.class) @contextconfiguration(loader = annotationconfigcontextloader.class, classes = { testconfig.class }) public class familyservicetest {      @configuration     @componentscan(basepackageclasses = { com.bonevich.ancestral.family.familyserviceimpl.class }, resourcepattern = "familyserviceimpl.class")     @enableneo4jrepositories(basepackageclasses = { com.bonevich.ancestral.family.familynode.class })     static class testconfig extends neo4jconfiguration {         @bean         public graphdatabaseservice graphdatabaseservice() {             return new graphdatabasefactory().newembeddeddatabasebuilder("/data/neo4j/ancestral-familyservicetest/")                     .newgraphdatabase();         }     }      @autowired     private familyservice families;      @autowired     private graphdatabaseservice graphdatabaseservice;      @autowired     private neo4jtemplate neo4jtemplate;      @test     public void testupdatefamily() {         this.families.createfamily(familynode.instance("testfamily"));          transaction tx = this.graphdatabaseservice.begintx();         personnode person = personnode.instance("john", "johanson", "m", "a_person");         personnode expectedchild = this.neo4jtemplate.save(person);         final long childid = expectedchild.getidentifier();         tx.success();         tx.finish();          family actualfamily = this.families.updatefamily("testfamily", new familynodeupdater() {             @override             public familynode update(familynode family) {                 family.addchild(familyservicetest.this.neo4jtemplate.findone(childid, personnode.class));                 return family;             }         });          assertthat(actualfamily.getid(), is("testfamily"));         assertthat(actualfamily.getchildren().get(0), is((person) expectedchild));     }  } 

running test yields following exception stack:

org.neo4j.graphdb.notintransactionexception     @ org.neo4j.kernel.impl.core.notransactionstate.acquirewritelock(notransactionstate.java:43)     @ org.neo4j.kernel.impl.transaction.locktype$2.acquire(locktype.java:51)     @ org.neo4j.kernel.impl.core.nodemanager.getnodeforproxy(nodemanager.java:473)     @ org.neo4j.kernel.internalabstractgraphdatabase$6.lookup(internalabstractgraphdatabase.java:733)     @ org.neo4j.kernel.impl.core.nodeproxy.createrelationshipto(nodeproxy.java:207)     @ org.springframework.data.neo4j.fieldaccess.relationshiphelper.obtainsinglerelationship(relationshiphelper.java:62)     @ org.springframework.data.neo4j.fieldaccess.relationshiphelper.createsinglerelationship(relationshiphelper.java:142)     @ org.springframework.data.neo4j.fieldaccess.relationshiphelper.createaddedrelationships(relationshiphelper.java:96)     @ org.springframework.data.neo4j.fieldaccess.relatedtofieldaccessor.createaddedrelationships(relatedtofieldaccessor.java:78)     @ org.springframework.data.neo4j.fieldaccess.relatedtocollectionfieldaccessorfactory$relatedtocollectionfieldaccessor.setvalue(relatedtocollectionfieldaccessorfactory.java:68)     @ org.springframework.data.neo4j.fieldaccess.managedfieldaccessorset.updatevalue(managedfieldaccessorset.java:112)     @ org.springframework.data.neo4j.fieldaccess.managedfieldaccessorset.update(managedfieldaccessorset.java:100)     @ org.springframework.data.neo4j.fieldaccess.managedfieldaccessorset.add(managedfieldaccessorset.java:126)     @ com.bonevich.ancestral.family.familynode.addchild(familynode.java:124)     @ com.bonevich.ancestral.family.familyservicetest$1.update(familyservicetest.java:64)     @ com.bonevich.ancestral.family.familyserviceimpl.updatefamily(familyserviceimpl.java:42)     @ com.bonevich.ancestral.family.familyservicetest.testupdatefamily(familyservicetest.java:61)     @ sun.reflect.nativemethodaccessorimpl.invoke0(native method)     @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:57)     @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)     @ java.lang.reflect.method.invoke(method.java:606)     @ org.junit.runners.model.frameworkmethod$1.runreflectivecall(frameworkmethod.java:47)     @ org.junit.internal.runners.model.reflectivecallable.run(reflectivecallable.java:12)     @ org.junit.runners.model.frameworkmethod.invokeexplosively(frameworkmethod.java:44)     @ org.junit.internal.runners.statements.invokemethod.evaluate(invokemethod.java:17)     @ org.springframework.test.context.junit4.statements.runbeforetestmethodcallbacks.evaluate(runbeforetestmethodcallbacks.java:74)     @ org.springframework.test.context.junit4.statements.runaftertestmethodcallbacks.evaluate(runaftertestmethodcallbacks.java:83)     @ org.springframework.test.context.junit4.statements.springrepeat.evaluate(springrepeat.java:72)     @ org.springframework.test.context.junit4.springjunit4classrunner.runchild(springjunit4classrunner.java:231)     @ org.springframework.test.context.junit4.springjunit4classrunner.runchild(springjunit4classrunner.java:88)     @ org.junit.runners.parentrunner$3.run(parentrunner.java:238)     @ org.junit.runners.parentrunner$1.schedule(parentrunner.java:63)     @ org.junit.runners.parentrunner.runchildren(parentrunner.java:236)     @ org.junit.runners.parentrunner.access$000(parentrunner.java:53)     @ org.junit.runners.parentrunner$2.evaluate(parentrunner.java:229)     @ org.springframework.test.context.junit4.statements.runbeforetestclasscallbacks.evaluate(runbeforetestclasscallbacks.java:61)     @ org.springframework.test.context.junit4.statements.runaftertestclasscallbacks.evaluate(runaftertestclasscallbacks.java:71)     @ org.junit.runners.parentrunner.run(parentrunner.java:309)     @ org.springframework.test.context.junit4.springjunit4classrunner.run(springjunit4classrunner.java:174)     @ org.eclipse.jdt.internal.junit4.runner.junit4testreference.run(junit4testreference.java:50)     @ org.eclipse.jdt.internal.junit.runner.testexecution.run(testexecution.java:38)     @ org.eclipse.jdt.internal.junit.runner.remotetestrunner.runtests(remotetestrunner.java:467)     @ org.eclipse.jdt.internal.junit.runner.remotetestrunner.runtests(remotetestrunner.java:683)     @ org.eclipse.jdt.internal.junit.runner.remotetestrunner.run(remotetestrunner.java:390)     @ org.eclipse.jdt.internal.junit.runner.remotetestrunner.main(remotetestrunner.java:197) 

i have got believe missing in configuring sdn or transactions, have been unable track down.

i answered question here: spring data neo4j - notintransactionexception while modifying set of nodeentity

in short, has fact these list special list backed sdn , modification persisted db. if want prevent behaviour, should use iterable in model classes. if have more question after reading link, post them comment.


Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -