Warm tip: This article is reproduced from stackoverflow.com, please click
neo4j-ogm

Can we update a RelationshipEntity to point to a different NodeEntity?

发布于 2020-03-30 21:14:23

Using Neo4j-OGM I'm trying to update a @RelationshipEntity to point to a different node object. But when I try to persist the change, it doesn't get saved, it just reverts back to the original entity.

For example, this is what I want to achieve:

from:    (X)--[R]->(M)    (Y)

  to:    (Y)--[R]->(M)    (X)

I've made an example in the CineastsRelationshipEntityTest integration test:

@Test
public void canUpdateRelationshipEntity() {
    Movie movie = new Movie("M", 2020);

    Actor actor = new Actor("X");
    Role relationship = actor.playedIn(movie, "R");

    Actor actor2 = new Actor("Y");
    actor2.setRoles(new HashSet<>());

    assertThat(actor.getRoles()).hasSize(1);
    assertThat(actor2.getRoles()).hasSize(0);

    session.save(actor);
    session.save(actor2);

    session.clear();


    // try to update the relationship:
    relationship.setActor(actor2);
    actor.getRoles().remove(relationship);
    actor2.getRoles().add(relationship);

    assertThat(actor.getRoles()).hasSize(0);
    assertThat(actor2.getRoles()).hasSize(1);

    session.save(actor);
    session.save(actor2);

    session.clear();



    Actor loadedActor = session.load(Actor.class, actor.getUuid());
    Actor loadedActor2 = session.load(Actor.class, actor2.getUuid());

    assertThat(loadedActor.getRoles()).hasSize(0);
    assertThat(loadedActor2.getRoles()).hasSize(1);
}

At the end, loadedActor and loadedActor2 do not reflect the updated relationship.

Questioner
cmosher01
Viewed
15
meistermeier 2020-01-31 18:13

You could do this with focus on keeping the properties in the Role instance. But you have to reset the id when you try to update. A relationship is nothing you could reuse but must get recreated.

Neo4j-OGM assumes with a given id that only properties has changed and not the start or end node.

Some remarks on your test case:

  • if you call session.clear() (after the first saves), you have to reload the actors before manipulating your model to make Neo4j-OGM aware of the changes.
  • It would be enough to save just the actor. The save cascades to all reachable nodes and relationships. Even in the case of removal this should work if you respect the first remark ;)