Обновление узла без его предварительного извлечения с помощью Neo4j OGM

У меня есть структура, которая (упрощенно) выглядит так:

@NodeEntity(label = "Entity")
class FullEntity {

    @Id @GeneratedValue
    var _id: Long? = null

    @Id @Index(unique = true)
    lateinit var uuid: String

    lateinit var someMoreData: String // this data is sometimes lost

    @Relationship(type = "TARGETS", direction = Relationship.OUTGOING)
    var target: StubEntity? = null
}

@NodeEntity(label = "Entity")
class StubEntity {

    @Id @GeneratedValue
    var _id: Long? = null

    @Id @Index(unique = true)
    lateinit var uuid: String
}

@RepositoryRestResource
interface EntityRepository : Neo4jRepository<FullEntity, Long>

Теперь, когда я сохраняю два связанных объекта FullEntity независимо друг от друга, все работает, если я делаю это одним способом:

entityRepository.save(FullEntity().apply {
    uuid = "uuid1"
    someMoreData = "SomeMoreData1"
    target = StubEntity().apply {
        uuid = "uuid2"
    }
})
// some time later ...
entityRepository.save(FullEntity().apply {
    uuid = "uuid2"
    someMoreData = "SomeMoreData2"
})

но если я изменю порядок так:

entityRepository.save(FullEntity().apply {
    uuid = "uuid2"
    someMoreData = "SomeMoreData2"
})
// some time later ...
entityRepository.save(FullEntity().apply {
    uuid = "uuid1"
    someMoreData = "SomeMoreData1"
    target = StubEntity().apply {
        uuid = "uuid2"
    }
})

он удаляет "SomeMoreData2".


person MaciejGórski    schedule 06.02.2018    source источник
comment
Я могу каким-то образом воспроизвести вашу проблему, но мне нужно время для анализа. Одна вещь, которую я заметил, это то, что если вы активируете индексы, это не создаст записи, так как вам нужна уникальность uuid для заметок с меткой Entity. Но вы также можете помочь мне понять ваш вариант использования: почему вы определяете несколько полей Id?   -  person meistermeier    schedule 07.02.2018
comment
@meistermeier У меня действительно есть уникальное ограничение (и индекс тоже) для этого uuid. _id — это внутренний идентификатор в базе данных Neo, который я нигде не использую.   -  person MaciejGórski    schedule 07.02.2018


Ответы (1)


Я вижу две проблемы с вашими классами и использованием в OGM:

  1. Вы используете ярлык Entity дважды. Это создаст проблемы, если OGM попытается загрузить данные из Neo4j. Он не может найти правильный тип для присвоения значений. Возможные обходные пути:

    • Явно установите для этого класса другую метку, например StubEntity.

    • Если это невозможно из-за уникальности uuid для обоих классов, вам может даже не понадобиться StubEntity, но использовать класс FullEntity также для цели отношения. Разницы в Neo4j после сохранения данных не будет.

    • Если оба класса имеют больше различий, чем показано в приведенном выше примере кода, вы можете создать абстрактный класс с меткой Entity, а также предоставить метки специального типа (неявные, просто аннотируя с помощью @NodeEntity, или явные с атрибутом метки, который вы уже используете) для реализации. классы. Чем вы могли бы использовать ограничение uuid в абстрактном классе.

  2. Использование аннотации @Id дважды. Нет необходимости объявлять дополнительное @Id в поле uuid, если вам просто нужно поле в индексе и уникальное ограничение (если я правильно понял ваш комментарий).

person meistermeier    schedule 08.02.2018