【问题标题】:What is the cause of Cannot merge node using null property value for uuid in Spring Data Neo4j starter and OGM SessionFactory?在 Spring Data Neo4j 启动器和 OGM SessionFactory 中无法使用 uuid 的空属性值合并节点的原因是什么?
【发布时间】:2018-07-06 02:59:32
【问题描述】:

显然这是一个常见的例外,但这里提出的所有问题似乎都与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.RELEASEsprng-boot-data-neo4j 启动器,它会拉下neo4j-ogm-core-3.1.0neo4j-ogm-bolt-driver-3.1.0neo4j-ogm-api-3.1.0 和神秘的neo4j-java-driver-1.5

我正在使用Neo4j OGM SessionFactory 来构建我自己的通用 DAO 层,而不是限制我使用的 Spring Data Repository

  • 所有域的单一存储库(即 loadById(classType, id))
  • 运行自定义密码查询
  • 其他一些我不记得的原因

问题

我能够执行CREATEREADDELETE 操作。 PUT 操作具有以下假设

  1. 之前创建的tn:TestNodet1:TestNodeTargett2:TestNodeTarget
  2. tn 节点与t1 节点有关系
  3. 检索tn节点,t1 & t2节点
  4. tn 节点关系从t1 更改为t2
  5. 致电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$5.run(SingleThreadEventExecutor.java:858)
    at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)

问题

  1. 错误Caused by: org.neo4j.driver.v1.exceptions.ClientException: Cannot merge node using null property value for uuid 消息的根本原因是什么?节点uuid 值不为空。
  2. bolt-driverneo4j-java-driver 如何相互通信?看到neo4j-java-driver,我很惊讶。
  3. 既然我使用 Neo4j OGM 来支持 Spring Data 的 Repository 那么我可以放弃 spring-boot-starter-data-neo4j 吗?如果是,@Transactional 和事务管理会发生什么?

【问题讨论】:

    标签: java spring-boot neo4j spring-data-neo4j neo4j-ogm


    【解决方案1】:

    TL;DR

    使用带有@Id 注释的UUID 字段不能替代private Long id 字段(或者是吗?)。将id 字段添加到类中,异常消失。

    我迫不及待地决定自己调试这个问题并分享我的发现

    交易

    起初,PUT 操作正常工作(没有private Long id 字段)但未能删除旧关系,基于此Github issue 我将操作包装在@Transactional 中,我得到了异常。一些进展。

    ORM 上下文中,上述内容可以正常工作。换句话说,我可以retrieve 来自@Transactional 注释的服务层的实体,在non-transactional 层中进行必要的更改,然后使用另一种使用@Transactional 注释的服务层方法persist 实体。对于OGM,您必须在同一个事务层中完成所有操作。哼!

    异常

    如上题所示,TestNode 实体使用UUID 如下

    @Id @GeneratedValue(strategy = UuidStrategy.class) 
    @Convert(UuidStringConverter.class)
    private UUID uuid;
    

    我必须更新TestNode 类以包含一个

    private Long id; 
    

    在此之后,PUT 操作按预期工作,旧关系被删除。

    困惑

    为什么缺少private Long id;只会导致更新时出现异常?当你 retrievedeletecreate 实体时,为什么不呢?

    【讨论】:

      猜你喜欢
      • 2016-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多