在使用自定义的AttributeConverter for Neo4j时获取Neo.ClientError.Statement.TypeError Spring Boot JPA

我有一个与Spring Data Neo4j(v5.0.0RC2),Neo4j(v3.2.1)和Neo4j OGM(v3.0.0)一起运行的Kotlin(v1.1.4)Spring Boot(v2.0.0.BUILD-SNAPSHOT)应用程序。

尝试对具有自定义AttributeConverter的字段使用自定义JPA @Query时收到以下错误。

堆栈跟踪:

  org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing Cypher; Code: Neo.ClientError.Statement.TypeError; Description: Property values can only be of primitive types or arrays thereof; nested exception is org.neo4j.ogm.exception.CypherException: Error executing Cypher; Code: Neo.ClientError.Statement.TypeError; Description: Property values can only be of primitive types or arrays thereof at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.springframework.data.neo4j.transaction.SessionFactoryUtils.convertOgmAccessException(SessionFactoryUtils.java:153) at org.springframework.data.neo4j.repository.support.SessionBeanDefinitionRegistrarPostProcessor.translateExceptionIfPossible(SessionBeanDefinitionRegistrarPostProcessor.java:71) at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:216) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) at com.sun.proxy.$Proxy158.createBelongsToRelationship(Unknown Source) at com.yellowbird.mbi.service.StoreServiceImpl.updateVendorStoreRelationship(StoreServiceImpl.kt:26) at com.yellowbird.mbi.service.StoreServiceImpl$$FastClassBySpringCGLIB$$e7299ffb.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke(AbstractTraceInterceptor.java:133) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) at com.yellowbird.mbi.service.StoreServiceImpl$$EnhancerBySpringCGLIB$$3e3291f9.updateVendorStoreRelationship() at com.yellowbird.mbi.service.StoreServiceIT.givenVendorId13_getVendorByVendorId_returnsVendorWithId13(StoreServiceIT.kt:28) 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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73) at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251) 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.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: org.neo4j.ogm.exception.CypherException: Error executing Cypher; Code: Neo.ClientError.Statement.TypeError; Description: Property values can only be of primitive types or arrays thereof at org.neo4j.ogm.drivers.embedded.request.EmbeddedRequest.executeRequest(EmbeddedRequest.java:176) at org.neo4j.ogm.drivers.embedded.request.EmbeddedRequest.execute(EmbeddedRequest.java:78) at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.executeAndMap(ExecuteQueriesDelegate.java:117) at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:86) at org.neo4j.ogm.session.Neo4jSession.query(Neo4jSession.java:391) 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.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.invoke(SharedSessionCreator.java:131) at com.sun.proxy.$Proxy145.query(Unknown Source) at org.springframework.data.neo4j.repository.query.GraphQueryExecution$SingleEntityExecution.execute(GraphQueryExecution.java:74) at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:77) at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:51) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:565) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:549) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:60) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ... 47 more Caused by: org.neo4j.graphdb.QueryExecutionException: Property values can only be of primitive types or arrays thereof at org.neo4j.kernel.impl.query.QueryExecutionKernelException.asUserException(QueryExecutionKernelException.java:35) at org.neo4j.kernel.impl.factory.ClassicCoreSPI.executeQuery(ClassicCoreSPI.java:82) at org.neo4j.kernel.impl.factory.GraphDatabaseFacade.execute(GraphDatabaseFacade.java:430) at org.neo4j.kernel.impl.factory.GraphDatabaseFacade.execute(GraphDatabaseFacade.java:413) at org.neo4j.ogm.drivers.embedded.request.EmbeddedRequest.executeRequest(EmbeddedRequest.java:172) ... 69 more Caused by: org.neo4j.kernel.impl.query.QueryExecutionKernelException: Property values can only be of primitive types or arrays thereof at org.neo4j.cypher.internal.javacompat.ExecutionEngine.executeQuery(ExecutionEngine.java:65) at org.neo4j.kernel.impl.factory.ClassicCoreSPI.executeQuery(ClassicCoreSPI.java:78) ... 72 more Caused by: org.neo4j.cypher.CypherTypeException: Property values can only be of primitive types or arrays thereof at org.neo4j.cypher.internal.compatibility.v3_2.exceptionHandler$.cypherTypeException(exceptionHandler.scala:60) at org.neo4j.cypher.internal.compatibility.v3_2.exceptionHandler$.cypherTypeException(exceptionHandler.scala:27) at org.neo4j.cypher.internal.frontend.v3_2.CypherTypeException.mapToPublic(CypherException.scala:48) at org.neo4j.cypher.internal.compatibility.v3_2.exceptionHandler$runSafely$.apply(exceptionHandler.scala:95) at org.neo4j.cypher.internal.compatibility.v3_2.Compatibility$ExecutionPlanWrapper.run(Compatibility.scala:100) at org.neo4j.cypher.internal.PreparedPlanExecution.execute(PreparedPlanExecution.scala:26) at org.neo4j.cypher.internal.ExecutionEngine.execute(ExecutionEngine.scala:107) at org.neo4j.cypher.internal.javacompat.ExecutionEngine.executeQuery(ExecutionEngine.java:61) ... 73 more Caused by: org.neo4j.cypher.internal.frontend.v3_2.CypherTypeException: Property values can only be of primitive types or arrays thereof at org.neo4j.cypher.internal.compiler.v3_2.helpers.CastSupport$.getConverter(CastSupport.scala:106) at org.neo4j.cypher.internal.compiler.v3_2.mutation.makeValueNeoSafe$.transformTraversableToArray(makeValueNeoSafe.scala:54) at org.neo4j.cypher.internal.compiler.v3_2.mutation.makeValueNeoSafe$.apply(makeValueNeoSafe.scala:29) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe.org$neo4j$cypher$internal$compiler$v3_2$pipes$BaseRelationshipPipe$$setProperty(CreateRelationshipPipe.scala:77) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe$$anonfun$setProperties$1$$anonfun$apply$1.apply(CreateRelationshipPipe.scala:63) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe$$anonfun$setProperties$1$$anonfun$apply$1.apply(CreateRelationshipPipe.scala:62) at scala.collection.immutable.Map$Map3.foreach(Map.scala:161) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe$$anonfun$setProperties$1.apply(CreateRelationshipPipe.scala:62) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe$$anonfun$setProperties$1.apply(CreateRelationshipPipe.scala:56) at scala.Option.foreach(Option.scala:257) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe.setProperties(CreateRelationshipPipe.scala:56) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe.org$neo4j$cypher$internal$compiler$v3_2$pipes$BaseRelationshipPipe$$createRelationship(CreateRelationshipPipe.scala:45) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe$$anonfun$internalCreateResults$1.apply(CreateRelationshipPipe.scala:38) at org.neo4j.cypher.internal.compiler.v3_2.pipes.BaseRelationshipPipe$$anonfun$internalCreateResults$1.apply(CreateRelationshipPipe.scala:38) at scala.collection.Iterator$$anon$11.next(Iterator.scala:409) at scala.collection.Iterator$class.foreach(Iterator.scala:893) at scala.collection.AbstractIterator.foreach(Iterator.scala:1336) at org.neo4j.cypher.internal.compiler.v3_2.pipes.EagerAggregationPipe.internalCreateResults(EagerAggregationPipe.scala:89) at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:82) at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) at org.neo4j.cypher.internal.compiler.v3_2.pipes.PipeWithSource.createResults(Pipe.scala:79) at org.neo4j.cypher.internal.compiler.v3_2.executionplan.DefaultExecutionResultBuilderFactory$ExecutionWorkflowBuilder.createResults(DefaultExecutionResultBuilderFactory.scala:96) at org.neo4j.cypher.internal.compiler.v3_2.executionplan.DefaultExecutionResultBuilderFactory$ExecutionWorkflowBuilder.build(DefaultExecutionResultBuilderFactory.scala:74) at org.neo4j.cypher.internal.compiler.v3_2.BuildInterpretedExecutionPlan$$anonfun$getExecutionPlanFunction$1.apply(BuildInterpretedExecutionPlan.scala:103) at org.neo4j.cypher.internal.compiler.v3_2.BuildInterpretedExecutionPlan$$anonfun$getExecutionPlanFunction$1.apply(BuildInterpretedExecutionPlan.scala:86) at org.neo4j.cypher.internal.compiler.v3_2.BuildInterpretedExecutionPlan$$anon$1.run(BuildInterpretedExecutionPlan.scala:55) at org.neo4j.cypher.internal.compatibility.v3_2.Compatibility$ExecutionPlanWrapper$$anonfun$run$1.apply(Compatibility.scala:102) at org.neo4j.cypher.internal.compatibility.v3_2.Compatibility$ExecutionPlanWrapper$$anonfun$run$1.apply(Compatibility.scala:100) at org.neo4j.cypher.internal.compatibility.v3_2.exceptionHandler$runSafely$.apply(exceptionHandler.scala:90) ... 77 more 

这是我的转换器:

 class ZonedDateTimeStringConverter : AttributeConverter { companion object { private val DATE_TIME_FORMAT = DateTimeFormatter.ISO_OFFSET_DATE_TIME } override fun toGraphProperty(value: ZonedDateTime?): String? = when (value) { null -> null else -> DATE_TIME_FORMAT.format(value) } override fun toEntityAttribute(value: String?): ZonedDateTime? = when (value) { null -> null else -> ZonedDateTime.parse(value, DATE_TIME_FORMAT) } } 

我在这里有一个关系实体:

 @RelationshipEntity(type = "PART_OF") data class PartOf( /* * @GraphId, @StartNode, @EndNode defined here) */ @Convert(ZonedDateTimeStringConverter::class) var sinceDate: ZonedDateTime? = null ) 

我的JPA查询如下:

 @Query("MATCH (s:EntityOne {identifier: {entityOneIdentifier}})" + " MATCH (v:EntityTwo {identifier: {entitiyTwoIdentifier}})" + " CREATE (v)-[:PART_OF {createDate: {createDate}, sinceDate: {sinceDate}, active: {active}}]->(s) " + " RETURN count(s) > 0") fun createPartOfRelationship(@Param("entityOneIdentifier") entityOneId: Long, @Param("entityTwoIdentifier") entityTwoId: Long, @Param("createDate") createDate: ZonedDateTime, @Param("sinceDate") sinceDate: ZonedDateTime, @Param("active") active: Boolean): Boolean 

在线查看Neo4j参考资料的Spring数据,看起来我已经掌握了一切。 OGM正确地看到了转换器(我能够调试,并看到类中的静态companion object正在创建/命中。

所以,我认为Spring Data可能需要了解转换器。 所以,根据文档,我在我的spring配置中添加了一个ConversionService

 @Bean fun conversionService(@Autowired sessionFactory: SessionFactory): ConversionService = MetaDataDrivenConversionService(sessionFactory.metaData()) 

这使用java.util.Date工作,就像Spring Data Neo4j文档说的那样(它的自动配置)在这里陈述了: http : //docs.spring.io/spring-data/neo4j/docs/4.0.0.RELEASE/参考/ HTML /#reference_programming-model_conversion

有没有人有任何建议尝试或为什么这可能会发生?

这样的参数是不可能的

 @Param("createDate") createDate: ZonedDateTime 

@Query注释的存储库方法中。

在这种情况下,目标types是String ,但可以是IntegerDouble等。并且查询将是相同的 – SDN不知道您需要转换的types,因此您需要执行转换以更正types自己(用于查询参数)。

Interesting Posts