Что является причиной невозможности слияния узла, использующего нулевое значение свойства для uuid в Spring Data Neo4j starter и OGM SessionFactory? - PullRequest
0 голосов
/ 06 июля 2018

По-видимому, это распространенное исключение, но все вопросы, задаваемые здесь, похоже, связаны с CSV, поэтому и возникает вопрос.

У меня есть domain объект, который использует uuid в качестве уникального идентификатора и объявлен следующим образом

@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 Data Repository, который ограничивает меня от

  • Единый репозиторий для всех доменов (т.е. loadById (classType, id))
  • Запуск пользовательских запросов шифров
  • Некоторые другие причины, которые я не помню

Выпуск

Я могу выполнять операции CREATE, READ и DELETE. Операции PUT со следующими допущениями

  1. Ранее созданные tn:TestNode, t1:TestNodeTarget и t2:TestNodeTarget
  2. Узел tn связан с t1 узлом
  3. Получить tn узел, t1 & t2 узел
  4. Измените отношение узла tn на 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-driver.
  3. Поскольку я использую Neo4j OGM в пользу Spring Data Repository, могу ли я отказаться от spring-boot-starter-data-neo4j? Если да, что происходит с @Transactional и управлением транзакциями?

1 Ответ

0 голосов
/ 06 июля 2018

TL; DR

Использование поля UUID с пометкой @Id не является заменой поля private Long id (или это?). Добавьте поле id в класс, и исключение исчезнет.

Я не мог дождаться и решил самостоятельно отладить эту проблему и поделиться своими выводами

Сделка

Сначала операция PUT работала (без поля private Long id) без исключения, но не смогла удалить старую связь и, основываясь на этой проблеме Github Я завернула операции в @Transactional и Я получил исключение. Некоторый прогресс.

В контексте ORM вышеприведенное будет работать нормально. Другими словами, я могу retrieve объект из @Transactional аннотированного сервисного уровня, внести необходимые изменения в non-transactional слой и затем persist объект, используя другой метод сервисного уровня, который аннотирован @Transactional. Для OGM вы должны сделать все это на одном уровне транзакций. Hum!

Исключение

Как показано в приведенном выше вопросе, сущность TestNode использует UUID следующим образом

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

Мне пришлось обновить TestNode класс, чтобы включить

private Long id; 

И после этого операция PUT работает, как ожидалось, и старые отношения удаляются.

Беспорядки

Почему отсутствие private Long id; вызывает исключение только во время обновления? Почему нет, когда вы retrieve, delete или create сущность?

...