代码之家  ›  专栏  ›  技术社区  ›  Raf

在spring data neo4j starter和ogm sessionfactory中使用uuid的空属性值无法合并节点的原因是什么?

  •  2
  • Raf  · 技术社区  · 8 年前

    显然这是一个常见的例外,但是,这里提出的所有问题似乎都与 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层,而不是限制我

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

    发行

    我能表演 CREATE 我是说, READ DELETE 操作。这个 PUT 具有以下假设的操作

    1. 以前创建的 tn:TestNode ,请 t1:TestNodeTarget t2:TestNodeTarget
    2. 这个 tn 节点与 t1 节点
    3. 检索 总氮 节点, t1 & t2 节点
    4. 更改 总氮 节点关系到 t2 T1级
    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-driver neo4j-java-driver 互相沟通?我很惊讶地看到 Neo4J Java驱动程序 是的。
    3. 因为我在用 Neo4j OGM 支持Spring Data的 Repository 那我能把 spring-boot-starter-data-neo4j 是吗?如果是的话, @Transactional 还有交易管理?
    1 回复  |  直到 8 年前
        1
  •  1
  •   Raf    8 年前

    TL;博士

    使用A UUID 字段注释为 @Id 不能取代 private Long id 字段(还是它?)。添加 id 字段,异常将消失。

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

    交易

    一开始, PUT 操作成功(没有 私人长ID 字段)没有异常,但未能删除旧关系,基于此 Github issue 我把手术包在 @Transactional 我有个例外。一些进展。

    ORM 上下文中,上面的代码可以正常工作。换句话说,我可以 retrieve 实体来自 @事务性 带注释的服务层,在 non-transactional 一层然后 persist 使用另一个服务层方法的实体,该方法用 @事务性 是的。为了 OGM 你必须在同一个事务层中完成。哼!

    例外情况

    如上面的问题所示, TestNode 实体利用 Uuid公司 如下所示

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

    我必须更新 测试节点 类包括

    private Long id; 
    

    在这之后 投入 操作按预期工作,旧关系将被删除。

    困惑

    为什么缺少 private Long id; 只在更新期间导致异常?为什么不当你 检索 我是说, delete ,或 create 实体?