Neo4j Liquigraph和变更设置与APOC触发器

时间:2018-03-10 13:33:00

标签: neo4j cypher neo4j-apoc liquigraph

我想用Liquigraph变更集安装以下触发器:

<changeset id="create_decision_characteristic_value_relationship_trigger">
    <query>CALL apoc.trigger.add('HAS_VALUE_ON_ADD_TO_INDEX', 'UNWIND {createdRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(ch:Characteristic) CALL apoc.index.addRelationship(r, keys(r)) RETURN count(*)', {phase:'after'});</query>
    <query>CALL apoc.trigger.add('HAS_VALUE_ON_REMOVE_FROM_INDEX', "UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)", {phase:'after'});</query>
</changeset>

但是应用程序失败,出现以下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:107)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:242)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'neo4jAuditionBeanFactoryPostProcessor': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [com/decisionwanted/domain/configuration/Neo4jConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquigraph' defined in class path resource [org/liquigraph/spring/starter/LiquigraphAutoConfiguration$LiquigraphConfiguration.class]: Invocation of init method failed; nested exception is java.lang.RuntimeException: java.sql.SQLException: Some errors occurred : 
[Neo.ClientError.Statement.SyntaxError]:Invalid input 'H': expected whitespace, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',' or ')' (line 1, column 189 (offset: 188))
"CALL apoc.trigger.add('HAS_VALUE_ON_REMOVE_FROM_INDEX', 'UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)', {phase:'after'});"
                                                                                                                                                                                             ^

    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:729)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:192)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1270)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:238)
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:709)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:534)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:138)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
    ... 26 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [com/decisionwanted/domain/configuration/Neo4jConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquigraph' defined in class path resource [org/liquigraph/spring/starter/LiquigraphAutoConfiguration$LiquigraphConfiguration.class]: Invocation of init method failed; nested exception is java.lang.RuntimeException: java.sql.SQLException: Some errors occurred : 
[Neo.ClientError.Statement.SyntaxError]:Invalid input 'H': expected whitespace, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',' or ')' (line 1, column 189 (offset: 188))
"CALL apoc.trigger.add('HAS_VALUE_ON_REMOVE_FROM_INDEX', 'UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)', {phase:'after'});"
                                                                                                                                                                                             ^

    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:815)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:721)
    ... 44 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquigraph' defined in class path resource [org/liquigraph/spring/starter/LiquigraphAutoConfiguration$LiquigraphConfiguration.class]: Invocation of init method failed; nested exception is java.lang.RuntimeException: java.sql.SQLException: Some errors occurred : 
[Neo.ClientError.Statement.SyntaxError]:Invalid input 'H': expected whitespace, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',' or ')' (line 1, column 189 (offset: 188))
"CALL apoc.trigger.add('HAS_VALUE_ON_REMOVE_FROM_INDEX', 'UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)', {phase:'after'});"
                                                                                                                                                                                             ^

    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579)
    ... 57 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquigraph' defined in class path resource [org/liquigraph/spring/starter/LiquigraphAutoConfiguration$LiquigraphConfiguration.class]: Invocation of init method failed; nested exception is java.lang.RuntimeException: java.sql.SQLException: Some errors occurred : 
[Neo.ClientError.Statement.SyntaxError]:Invalid input 'H': expected whitespace, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',' or ')' (line 1, column 189 (offset: 188))
"CALL apoc.trigger.add('HAS_VALUE_ON_REMOVE_FROM_INDEX', 'UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)', {phase:'after'});"
                                                                                                                                                                                             ^

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1710)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:583)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.resolveBeanReference(ConfigurationClassEnhancer.java:392)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:364)
    at com.decisionwanted.domain.configuration.Neo4jConfig$$EnhancerBySpringCGLIB$$7e91e1f.configuration(<generated>)
    at com.decisionwanted.domain.configuration.Neo4jConfig.sessionFactory(Neo4jConfig.java:42)
    at com.decisionwanted.domain.configuration.Neo4jConfig$$EnhancerBySpringCGLIB$$7e91e1f.CGLIB$sessionFactory$3(<generated>)
    at com.decisionwanted.domain.configuration.Neo4jConfig$$EnhancerBySpringCGLIB$$7e91e1f$$FastClassBySpringCGLIB$$cc165cbf.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361)
    at com.decisionwanted.domain.configuration.Neo4jConfig$$EnhancerBySpringCGLIB$$7e91e1f.sessionFactory(<generated>)
    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.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 58 more
Caused by: java.lang.RuntimeException: java.sql.SQLException: Some errors occurred : 
[Neo.ClientError.Statement.SyntaxError]:Invalid input 'H': expected whitespace, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',' or ')' (line 1, column 189 (offset: 188))
"CALL apoc.trigger.add('HAS_VALUE_ON_REMOVE_FROM_INDEX', 'UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)', {phase:'after'});"
                                                                                                                                                                                             ^

    at com.google.common.base.Throwables.propagate(Throwables.java:241)
    at org.liquigraph.core.io.ChangelogGraphWriter.executeStatement(ChangelogGraphWriter.java:102)
    at org.liquigraph.core.io.ChangelogGraphWriter.write(ChangelogGraphWriter.java:79)
    at org.liquigraph.core.api.MigrationRunner.writeApplicableChangesets(MigrationRunner.java:109)
    at org.liquigraph.core.api.MigrationRunner.runMigrations(MigrationRunner.java:80)
    at org.liquigraph.core.api.Liquigraph.runMigrations(Liquigraph.java:63)
    at org.liquigraph.spring.SpringLiquigraph.afterPropertiesSet(SpringLiquigraph.java:52)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706)
    ... 80 more
Caused by: java.sql.SQLException: Some errors occurred : 
[Neo.ClientError.Statement.SyntaxError]:Invalid input 'H': expected whitespace, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',' or ')' (line 1, column 189 (offset: 188))
"CALL apoc.trigger.add('HAS_VALUE_ON_REMOVE_FROM_INDEX', 'UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)', {phase:'after'});"
                                                                                                                                                                                             ^

    at org.neo4j.jdbc.http.HttpNeo4jStatement.execute(HttpNeo4jStatement.java:58)
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
    at org.liquigraph.core.io.ChangelogGraphWriter.executeChangesetQueries(ChangelogGraphWriter.java:110)
    at org.liquigraph.core.io.ChangelogGraphWriter.executeStatement(ChangelogGraphWriter.java:96)
    ... 87 more

这很奇怪,因为我可以手动安装这些触发器,例如通过Neo4j Web浏览器。

如何通过Liquigraph变更集正确安装这些触发器?

已更新

以下触发器声明导致问题。

<query>CALL apoc.trigger.add('HAS_VALUE_ON_REMOVE_FROM_INDEX', "UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)", {phase:'after'});</query>

第一个触发器可以正常使用Liquigraph。

我还尝试了CDATA的解决方案:

<query><![CDATA[CALL apoc.trigger.add('RELATIONSHIP_INDEX_ADD_HAS_VALUE_ON', 'UNWIND {createdRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(ch:Characteristic) CALL apoc.index.addRelationship(r, keys(r)) RETURN count(*)', {phase:'after'});]]></query>
<query><![CDATA[CALL apoc.trigger.add('RELATIONSHIP_INDEX_REMOVE_HAS_VALUE_ON', "UNWIND {deletedRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(ch:Characteristic) CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)", {phase:'after'});]]></query>

但它仍然无法解决同一问题。

请注意第一个触发器:

 <query>CALL apoc.trigger.add('HAS_VALUE_ON_ADD_TO_INDEX', 'UNWIND {createdRelationships} AS r MATCH (d:Decision)-[r:HAS_VALUE_ON]->(ch:Characteristic) CALL apoc.index.addRelationship(r, keys(r)) RETURN count(*)', {phase:'after'});</query>

即使没有CDATA部分也能正常工作,所以看起来Liquigraph不喜欢第二个触发器声明。

1 个答案:

答案 0 :(得分:1)

您必须将查询包装在<![CDATA[]]>中,否则关系箭头将由XML解析器解释。

更新:HTTP的基础JDBC驱动程序有一个关于查询清理的错误,现在已合并:https://github.com/neo4j-contrib/neo4j-jdbc/pull/129。如果要在下一个版本之前测试修复,可以构建JDBC HTTP驱动程序的分支3.3,然后构建Liquigraph的主分支。