Spring Data Neo4j : @RelationshipProperties not getting deleted

Hello,

I’m quite new to SDN on Java and I could not find an explanation about how this works.

I have the current java :

@Node
public class Application {

@Id
private String name;


@Relationship(type = "EXPOSES", cascadeUpdate=false)
private List<Endpoint> endpoints;

@Relationship(type = "CALLS_HTTP", cascadeUpdate=false)
private List<CallHttp> callsHttp;

where Endpoint is another entity and CallHttps is a @RelationshipProperties class.

I kept the example quite simple.

The issue that I enconter is the following :

Let’s imagine that I currently have an Application which name is : “app1” having already endpoint1 and endpoint2. It also has 2 relations of type CallHttp callHttp1 and callHttp2 for example.

Then I want to update the node Application. To do that, first I get my Application “app1” using findOne(Example).

Once I got it, I do my processing which creates two new lists:

tempEndpoints = endpoint3

tempCallsHttp = callHttp3 callHttp4

(All objects are new entities, uuid (@Id) is equal to null)

I set the new lists on the entity that I got doing setEndpoints(tempEndpoints ) and setCallsHttp(tempCallsHttp).

Then I do repository.save to update app1.

What I would like to happen is :

The updated entity should have :

endpoints = endpoint3

callsHttp = callHttp3 callHttp4

What it really happens :

endpoints = endpoint3

callsHttp = callHttp1 callsHttp2 callHttp3 callsHttp4

SDN did not deleted callHttp1 callHttp2 for callsHttp list but for endpoints, it did what I was expecting for.

Is this normal ? Am I doing something wrong ?

Thank you.

Sorry that I missed your question.

Is the problem still present?
This is really not expected. From your explanation, both should behave the same. The default mode of SDN is to remove all relationships and recreate them.

Do you have any differences in the class definition between CallHttp and Endpoint ? Or did you maybe not override the callsHttp but added the new ones from tempCallsHttp to the list?

You could enable more verbose logging in your application to see what queries are getting created.

org.springframework.data.neo4j.cypher=debug

or trace if you also want to see the parameters.

(reference: Logging :: Spring Data Neo4j )

Hello and thank you for the reply.

After enabling debuging I think I found the issue.

My CallHttp class is the following :

@RelationshipProperties
public class CallsHttp {

@RelationshipId
private Long id;

@TargetNode
private HttpCallable app;

Where HttpCallable is an interface :

public interface HttpCallable {}

I did this because I wanted to do polymorphism. HttpCallable is implemented by two others nodes, Backend and RestAPI.

The request which will delete the relationships tries to find nodes with the label “HttpCallable” which I do not have any since interface has no @NodeNode annotation.

The solutions here would be to add @Node to HttpCallable inferface which will then add also HttpCallable label to node Backend and RestAPI or to create two lists :

@Relationship(type = "CALLS_HTTP", cascadeUpdate=false)
private List<Backend> backends;

@Relationship(type = "CALLS_HTTP", cascadeUpdate=false)
private List<RestAPI> restApis;

and not to use the interface ?

On insertion, I do not have any issue.

Again thank you for the help.

You’re quite spot on. A few more details:
The save works fine from your perspective because the implementations define their own labels.
On the other side also the loading seems to work exactly as we intended it to do: Use the class (in your case the interface) name if no label is specified.

What hits you here is that the label is :HttpCallable und not :Backend or :RestAPI, as you have already noticed.
Adding the node annotation now to the interface will result in :HttpCallable:Backend and :HttpCallable:RestAPI for the nodes written to Neo4j. Basically, the writing is the root cause of your problem because it’s missing out the :HttpCallable label and the load mechanism cannot find the nodes.

Is there any reason why you don’t want to have the label in the database? My expectation would be to also represent in the graph that :Backend and :RestAPI are :HttpCallable , to express that they have something in common.

Indeed they do have that in common. After adding the @Node, everything works as expected.

Once again thank you for your time and your help !