I’m encountering an issue with node persistence in my project. I have two nodes: Movie
and Actor
. The Movie
node has a property of Actor
. Here’s a simplified version of my code:
@Node
class Movie {
String title;
Actor topActor;
}
@Node
class Actor {
String name;
}
When I create and save a Movie
and an Actor
like this:
Movie movie = new Movie("Polar Express");
Actor actor = new Actor("Tom Hanks");
movie.setTopActor(actor);
Both the Movie
and Actor
nodes get saved, which is expected.
However,
movie.setLength("1:26");
when I update the Movie
node, the updatedAt
field of both the Movie
and Actor
nodes gets updated. I expected only the updatedAt
field of the Movie
node to be updated.
Can anyone explain why this is happening and how I can prevent the updatedAt
field of the Actor
node from being updated when only the Movie
node is updated?
How are you updating it? Can you share the code?
Your domain object is the movie node. I assume you are finding it, updating the movie attribute, then saving the movie node. I believe the entire movie node gets recreated, which includes the actor node, when you save. You can see this if you turn on logging. It will log the cypher statements.
The explanation given by @glilienfield is correct. Spring Data Neo4j will traverse through all reachable objects and update them (even if there isn't anything to update). This will update the updated
values.
You can statically block those updates but would require to take care of the updates of the Actor
when needed with its own repository.
The @Relationship
annotation has a newer property cascadeUpdates
. If set to false, SDN will not process the related entity when you are persisting the class where the relationship is defined. In your case the Movie
class.
The issue you're facing is as follows:
@Node
class Movie {
String title;
@Relationship(type = "HAS", direction = Relationship.Direction.INCOMING, cascadeUpdates = false)
Actor topActor;
}
@Node
class Actor {
String name;
@Relationship(type = "HAS", direction = Relationship.Direction.INCOMING)
private AdditionalDetails additionalDetails;
}
@Node
class AdditionalDetails {
String address;
String location;
}
In this case, you want to save the Actor
along with AdditionalDetails
, so cascadeUpdates
should be true
by default. However, when you're saving the Movie
, the Actor
is not getting updated because cascadeUpdates
is set to false
, but its updating AdditionalDetails
Why ???
Expected behavior: On Movie
update Only the Movie
should be updated.
On Actor
update The Actor
and AdditionalDetails
both should get updated
@gerrit.meier @glilienfield can you help us with the above one