Cannot merge node using null 属性 value for uuid in Spring Data Neo4j starter 和 OGM SessionFactory 的原因是什么?
What is the cause of Cannot merge node using null property value for uuid in Spring Data Neo4j starter and OGM SessionFactory?
显然这是一个常见的例外,但是,这里提出的所有问题似乎都与 CSV
有关,因此,为什么要问这个问题。
我有一个 domain
对象,它使用 uuid
作为唯一 ID,声明如下
@NodeEntity(label = "TNODE")
public class TestNode {
@Id @GeneratedValue(strategy = UuidStrategy.class)
@Convert(UuidStringConverter.class)
private UUID uuid;
private String name;
@Relationship(type = "TEST_REL_IS", direction = Relationship.OUTGOING) private TestNodeTarget testTarget;
public TestNode() {}
public TestNode(String name, TestNodeTarget target) {
this.name = name;
this.testTarget = target;
}
//getters and setters
}
而TestNodeTarget
如下
@NodeEntity(label = "TNODE_TARGET")
public class TestNodeTarget {
private Long id;
private String name;
public TestNodeTarget() {}
public TestNodeTarget(String name) {
this.name = name;
}
//getters and setters
}
我正在使用 Spring Boot 2.0.3.RELEASE
和 sprng-boot-data-neo4j
启动器,它可以拉下 neo4j-ogm-core-3.1.0
、neo4j-ogm-bolt-driver-3.1.0
、neo4j-ogm-api-3.1.0
和神秘的 neo4j-java-driver-1.5
。
我正在使用 Neo4j OGM SessionFactory
构建我自己的通用 DAO 层,而不是 Spring 限制我使用
的数据存储库
- 所有域的单一存储库(即 loadById(classType, id))
- 运行 自定义密码查询
- 其他一些我不记得的原因
问题
我能够执行 CREATE
、READ
和 DELETE
操作。具有以下假设的 PUT
操作
- 之前创建了
tn:TestNode
、t1:TestNodeTarget
和 t2:TestNodeTarget
tn
节点与t1
节点有关系
- 检索
tn
个节点,t1 & t2
个节点
- 将
tn
节点关系从 t1
更改为 t2
- 呼叫
session.save
例外是
Caused by: org.neo4j.driver.v1.exceptions.ClientException: Cannot merge node using null property value for uuid
at org.neo4j.driver.internal.util.ErrorUtil.newNeo4jError(ErrorUtil.java:62)
at org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher.handleFailureMessage(InboundMessageDispatcher.java:137)
at org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1$Reader.unpackFailureMessage(PackStreamMessageFormatV1.java:432)
at org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1$Reader.read(PackStreamMessageFormatV1.java:396)
at org.neo4j.driver.internal.async.inbound.InboundMessageHandler.channelRead0(InboundMessageHandler.java:83)
at org.neo4j.driver.internal.async.inbound.InboundMessageHandler.channelRead0(InboundMessageHandler.java:35)
at org.neo4j.driver.internal.shaded.io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
at org.neo4j.driver.internal.async.inbound.MessageDecoder.channelRead(MessageDecoder.java:40)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:297)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:413)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at org.neo4j.driver.internal.shaded.io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1336)
at org.neo4j.driver.internal.shaded.io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1127)
at org.neo4j.driver.internal.shaded.io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1162)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
问题
- 错误
Caused by: org.neo4j.driver.v1.exceptions.ClientException: Cannot merge node using null property value for uuid
消息的根本原因是什么?节点 uuid
值不为空。
bolt-driver
和 neo4j-java-driver
如何相互通信?我很惊讶地看到 neo4j-java-driver
。
- 因为我使用
Neo4j OGM
支持 Spring 数据的 Repository
那么我可以放弃 spring-boot-starter-data-neo4j
吗?如果是,@Transactional
和事务管理会怎样?
TL;DR
使用带有 @Id
注释的 UUID
字段不能替代 private Long id
字段(或者是吗?)。将 id
字段添加到 class 中,异常消失。
我迫不及待地决定自己调试这个问题并分享我的发现
交易
起初,PUT
操作(没有 private Long id
字段)无一例外地工作但未能删除旧关系,基于此 Github issue 我将操作包装在 @Transactional
我得到了例外。一些进展。
在 ORM
上下文中,上面的方法可以正常工作。换句话说,我可以 retrieve
来自 @Transactional
注释服务层的实体,在 non-transactional
层中进行必要的更改,然后 persist
使用另一个服务层方法的实体用 @Transactional
注释。对于 OGM
,您必须在同一事务层中完成所有操作。哼!
异常
如上述问题所示,TestNode
实体使用 UUID
如下
@Id @GeneratedValue(strategy = UuidStrategy.class)
@Convert(UuidStringConverter.class)
private UUID uuid;
我必须更新 TestNode
class 以包含
private Long id;
在此之后,PUT
操作按预期工作,旧关系被删除。
困惑
为什么缺少private Long id;
只会导致更新时出现异常?为什么不在 retrieve
、delete
或 create
实体时呢?
显然这是一个常见的例外,但是,这里提出的所有问题似乎都与 CSV
有关,因此,为什么要问这个问题。
我有一个 domain
对象,它使用 uuid
作为唯一 ID,声明如下
@NodeEntity(label = "TNODE")
public class TestNode {
@Id @GeneratedValue(strategy = UuidStrategy.class)
@Convert(UuidStringConverter.class)
private UUID uuid;
private String name;
@Relationship(type = "TEST_REL_IS", direction = Relationship.OUTGOING) private TestNodeTarget testTarget;
public TestNode() {}
public TestNode(String name, TestNodeTarget target) {
this.name = name;
this.testTarget = target;
}
//getters and setters
}
而TestNodeTarget
如下
@NodeEntity(label = "TNODE_TARGET")
public class TestNodeTarget {
private Long id;
private String name;
public TestNodeTarget() {}
public TestNodeTarget(String name) {
this.name = name;
}
//getters and setters
}
我正在使用 Spring Boot 2.0.3.RELEASE
和 sprng-boot-data-neo4j
启动器,它可以拉下 neo4j-ogm-core-3.1.0
、neo4j-ogm-bolt-driver-3.1.0
、neo4j-ogm-api-3.1.0
和神秘的 neo4j-java-driver-1.5
。
我正在使用 Neo4j OGM SessionFactory
构建我自己的通用 DAO 层,而不是 Spring 限制我使用
- 所有域的单一存储库(即 loadById(classType, id))
- 运行 自定义密码查询
- 其他一些我不记得的原因
问题
我能够执行 CREATE
、READ
和 DELETE
操作。具有以下假设的 PUT
操作
- 之前创建了
tn:TestNode
、t1:TestNodeTarget
和t2:TestNodeTarget
tn
节点与t1
节点有关系- 检索
tn
个节点,t1 & t2
个节点 - 将
tn
节点关系从t1
更改为t2
- 呼叫
session.save
例外是
Caused by: org.neo4j.driver.v1.exceptions.ClientException: Cannot merge node using null property value for uuid
at org.neo4j.driver.internal.util.ErrorUtil.newNeo4jError(ErrorUtil.java:62)
at org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher.handleFailureMessage(InboundMessageDispatcher.java:137)
at org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1$Reader.unpackFailureMessage(PackStreamMessageFormatV1.java:432)
at org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1$Reader.read(PackStreamMessageFormatV1.java:396)
at org.neo4j.driver.internal.async.inbound.InboundMessageHandler.channelRead0(InboundMessageHandler.java:83)
at org.neo4j.driver.internal.async.inbound.InboundMessageHandler.channelRead0(InboundMessageHandler.java:35)
at org.neo4j.driver.internal.shaded.io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
at org.neo4j.driver.internal.async.inbound.MessageDecoder.channelRead(MessageDecoder.java:40)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:297)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:413)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at org.neo4j.driver.internal.shaded.io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1336)
at org.neo4j.driver.internal.shaded.io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1127)
at org.neo4j.driver.internal.shaded.io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1162)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
问题
- 错误
Caused by: org.neo4j.driver.v1.exceptions.ClientException: Cannot merge node using null property value for uuid
消息的根本原因是什么?节点uuid
值不为空。 bolt-driver
和neo4j-java-driver
如何相互通信?我很惊讶地看到neo4j-java-driver
。- 因为我使用
Neo4j OGM
支持 Spring 数据的Repository
那么我可以放弃spring-boot-starter-data-neo4j
吗?如果是,@Transactional
和事务管理会怎样?
TL;DR
使用带有 @Id
注释的 UUID
字段不能替代 private Long id
字段(或者是吗?)。将 id
字段添加到 class 中,异常消失。
我迫不及待地决定自己调试这个问题并分享我的发现
交易
起初,PUT
操作(没有 private Long id
字段)无一例外地工作但未能删除旧关系,基于此 Github issue 我将操作包装在 @Transactional
我得到了例外。一些进展。
在 ORM
上下文中,上面的方法可以正常工作。换句话说,我可以 retrieve
来自 @Transactional
注释服务层的实体,在 non-transactional
层中进行必要的更改,然后 persist
使用另一个服务层方法的实体用 @Transactional
注释。对于 OGM
,您必须在同一事务层中完成所有操作。哼!
异常
如上述问题所示,TestNode
实体使用 UUID
如下
@Id @GeneratedValue(strategy = UuidStrategy.class)
@Convert(UuidStringConverter.class)
private UUID uuid;
我必须更新 TestNode
class 以包含
private Long id;
在此之后,PUT
操作按预期工作,旧关系被删除。
困惑
为什么缺少private Long id;
只会导致更新时出现异常?为什么不在 retrieve
、delete
或 create
实体时呢?