I have a structure, which (simplified) looks like this:
@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>
Now when I save two related FullEntity objects independently, it all works if I do it one way:
entityRepository.save(FullEntity().apply {
uuid = "uuid1"
someMoreData = "SomeMoreData1"
target = StubEntity().apply {
uuid = "uuid2"
}
})
// some time later ...
entityRepository.save(FullEntity().apply {
uuid = "uuid2"
someMoreData = "SomeMoreData2"
})
but if I reverse the order like so:
entityRepository.save(FullEntity().apply {
uuid = "uuid2"
someMoreData = "SomeMoreData2"
})
// some time later ...
entityRepository.save(FullEntity().apply {
uuid = "uuid1"
someMoreData = "SomeMoreData1"
target = StubEntity().apply {
uuid = "uuid2"
}
})
it removes "SomeMoreData2".
I see two problems with your classes and the use in OGM:
You use the label
Entitytwice. This will create problems if OGM tries to load the data from Neo4j. It cannot find the right type to assign the values. Possible workarounds:Explicitly set the label to another one like
StubEntityfor this class.If this is not possible because the uniqueness of the uuid over both classes, you may not even need the
StubEntitybut use theFullEntityclass also for the relationship target. There will be no difference in Neo4j after saving the data.If both classes have more differences than the sample code above shows, you may create an abstract class with the
Entitylabel and also provide special type labels (implicit by just annotating with@NodeEntityor explicit with the label attribute you are already using) on the implementing classes. Than you could use the uuid constraint in the abstract class.Using the
@Idannotation twice. There is no need to declare an additional@Idon the uuid field if you just need the field in the index and an unique constraint (if I have understood your comment correct).