# How to correctly update a relationship

**URL:** <https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682>\
**Category:** Spring Data Neo4j & Neo4j-OGM\
**Tags:** relationship, cypher-dsl\
**Created:** [May 3, 2022, 8:01am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682 "2022-05-03T08:01:37Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 3, 2022, 8:01am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/1 "2022-05-03T08:01:37Z")

</div>

Hello ! I'm having problems to update the relation property.

Given the :

```auto
public class SomeEntity {

    @Id
    @GeneratedValue
    protected Long id;

    @Property
    protected String name;

    @Relationship
    protected Map<String, List<SomeLink>> relationships;
}

@RelationshipProperties
public class SomeLink {
    @Id
    @GeneratedValue
    protected Long id;

    @Property
    protected boolean active = true;

    @TargetNode
    protected SomeEntity target;
}

@Transactional
public interface SomeEntityRepository extends Neo4jRepository<SomeEntity, Long> {

    @Query("MATCH p=(n)-[*0..1]->(m) WHERE id(n)=$id RETURN n, collect(relationships(p)), collect(m);")
    Optional<SomeEntity> findByIdWithLevelOneLinks(@Param("id") Long id);
}

```

As a result, we have the graphe like:  
(n1:SomeEntity)-[r1:SomeLink]-\>(n2:SomeEntity)-[r2:SomeLink]-\>(n3:SomeEntity)-[...]-\>(...)

I want to update `r1`, but `r2` is removed if I use `findByIdWithLevelOneLinks` in the repository. It is comprehensible.

I tried to use the projections as suggested in [https://community.neo4j.com/t/relationships-eliminated-after-updating-node-properties/55117/4?u=pandalei97](https://community.neo4j.com/t/relationships-eliminated-after-updating-node-properties/55117/4)

```auto
public interface SomeEntityWithoutRelationship {
    Long getId();
    String getName();
}

public interface SomeEntityNodeWithOneLevelLinks {
    Long getId();
    String getName();
    Map<String, List<SomeLinkWithoutTargetRelationships>> getRelationships();
}

public interface SomeLinkWithoutTargetRelationships {
    Long getId();
    boolean isActive();
    SomeEntityWithoutRelationship getTarget();
}

```

Since projections only contains getters, I can't update the DTO that I retrieved. So I continue to use `SomeEntity` in the repository and when I update the node, I tried to do a `Projection projection = neo4jTemplate.saveAs(someEntityObject, SomeEntityNodeWithOneLevelLinks.class);`

But `r2` is still detached.

Please note that this is a simplified class. In our real class of `SomeEntity` and `SomeLink`, there are special setters and some composite properties. As a result, it is difficult to use Class-based Projections or Cypher-DSL.

I tried to solve this problem for several days but I still can't find a solution. Can someone help me ?

Thanks in advance for your response.

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 4, 2022, 6:47am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/2 "2022-05-04T06:47:52Z")

</div>

You are on the right track: Loading the entity as it is (without _all_ relationships) and persisting it via the `Neo4jTemplate#saveAs(entity, YourProjection.class)` should do the job.  
Sorry to hear that this is not working for you as expected. I am happy to investigate this because it might be the combination of dynamic relationships and relationship properties. Could you provide a reproducer for the problem? Maybe I have overseen something but I could not make it fail in our test base.

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 4, 2022, 4:00pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/3 "2022-05-04T16:00:45Z")

</div>

Hi Gerrit !

Thanks for your confirmation that I'm not on the wrong way.

I have created a simple demo here: [GitHub - Pandalei97/neo4jDemoBugRelationship](https://github.com/Pandalei97/neo4jDemoBugRelationship)

I defined hard coded examples in the controller to save time.

When I reproduce the problem, I found that it occurs when we use `@GeneratedValue`. When we use hard coded user-defined ID, it doesn't seem to detach the relationship. I hope that can give you a clearer vision of the solution.

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 5, 2022, 12:25pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/4 "2022-05-05T12:25:36Z")

</div>

I think that I have found the problem in the code base. It was the dynamic relationship.  
Created an issue to track [Projection support for dynamic relationships · Issue #2533 · spring-projects/spring-data-neo4j · GitHub](https://github.com/spring-projects/spring-data-neo4j/issues/2533)  
Also there is now a `6.2.5-GH-2533-SNAPSHOT` available to test. Would be helpful to get your feedback on this.  
To use the snapshot, you have to add Spring's snapshot (and milestone) repository to your pom.

```auto
<repositories>
  <repository>
    <id>spring-milestones</id>
    <name>Spring Milestones</name>
    <url>https://repo.spring.io/milestone</url>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
  </repository>
  <repository>
    <id>spring-snapshots</id>
    <name>Spring Snapshots</name>
    <url>https://repo.spring.io/snapshot</url>
    <releases>
      <enabled>false</enabled>
    </releases>
  </repository>
</repositories>

```

Thanks for the reproducer, it was really helpful.

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 6, 2022, 12:19pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/5 "2022-05-06T12:19:11Z")

</div>

Thanks a lot for the quick bugfix ! I have do several tests, it seems to work correctly now. I will do some more tests and give you a feedback these days. 😁

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 6, 2022, 12:34pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/6 "2022-05-06T12:34:22Z")

</div>

Thanks for the feedback. No hurry, I am still working on the tests for this.

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 10, 2022, 2:54pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/7 "2022-05-10T14:54:50Z")

</div>

Hi Gerrit,

I have found another use case where SDN doesn't seem to work correctly when multiple dynamic relationships exists in a class.

I have updated the demo in [GitHub - Pandalei97/neo4jDemoBugRelationship](https://github.com/Pandalei97/neo4jDemoBugRelationship)

The example is defined in the endpoint `createAnotherExample`. In the demo we can see that the nodes aren't created correctly.

Thanks in advance for your feedback.

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 11, 2022, 7:35am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/8 "2022-05-11T07:35:59Z")

</div>

But you are only persisting it via `neo4jTemplate.saveAs(n1, EntityWithOnlyOtherRelationshipProjection.class);`.  
where `EntityWithOnlyOtherRelationshipProjection` does only define the `otherRelationships`.  
This is the result I am looking at:  
 ![image](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/3X/f/e/feed6a48a1c45ebb8e852d9822fef5afaa0ce209.png)

Changing `EntityWithOnlyOtherRelationshipProjection` to extend `EntityWithOneLevelRelationshipProjection` will result in:  
 ![image](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/3X/4/d/4d3ddb34ef6845bccb28b406c2f0568292ef0aff.png)

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 11, 2022, 8:13am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/9 "2022-05-11T08:13:38Z")

</div>

Yes, that's exactly what I have. The target node of N1 is an empty node, which eventually leads to all links pointing to this same node.

Is it expected ?

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 11, 2022, 8:21am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/10 "2022-05-11T08:21:16Z")

</div>

Stupid me. Sorry, I have only looked at the mentioned problem with the relationship(s) and not the data in the target node itself. No, this should not happen, or I have missed something obvious.  
I will have a look and keep you updated.

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 11, 2022, 9:46am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/11 "2022-05-11T09:46:20Z")

</div>

Status update  
And now I know (again) why we initially did not support dynamic relationships in projections:  
When it comes to the detection of the defined paths in the projection interface/object tree, we rely on `PropertyPath` functionality of Spring Data commons. There is _one_ limitation: It does take the `Map` key but not the value as a valid part of the path. Adding `projection.relationships.id` will throw an exception, if I enforce this because it already claims that `relationships` is a `String` and not the projection/entity class.  
We have some kind of workaround this restriction in a related place in SDN and I am currently trying to replace the types. I cannot promise anything at this point and might rollback the already merged changes of GH-2533 and re-open it for later.  
Better not supporting this feature at the moment instead of a broken/incomplete solution.

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 11, 2022, 9:59am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/12 "2022-05-11T09:59:06Z")

</div>

Thanks for the investigation. This means that projection should not be used when we have dynamic relationships ?

Is there another solution to avoid the detachment of the relationship in this case or should I downgrade to SDN 5 ?

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 11, 2022, 5:23pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/13 "2022-05-11T17:23:54Z")

</div>

Alright. Nobody needs to downgrade 😉 There should be a `6.2.5-GH2533-2-SNAPSHOT` available now. There were more changes required than expected to make it work but I think it is now possible to do what you want. At least the example shows me the node properties and the related node because the projections points to the entity itself.  
 ![image](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/3X/3/3/33e31e9ef2ef11a95362943a4722c9cb6abf3d35.png)

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 11, 2022, 6:23pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/14 "2022-05-11T18:23:39Z")

</div>

Thanks a lot ! I will give you a feedback soon. You are a real hero !! 🥳 🎉

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 12, 2022, 9:52am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/15 "2022-05-12T09:52:39Z")

</div>

Hi Gerrit,

I think there may still exist a little problem for the entities without properties. This may be rare, but sometimes it's possible to get node with only relationships but no properties.

I just updated the reproducer. I created two simplified examples defined in with two new endpoints `createNodeWithoutProperties1` and `createNodeWithoutProperties2`.

The expected graphe to have for the two examples:  
`createNodeWithoutProperties1`:

```auto
(n1) -> (n2) -> (n3)

(n2)-> (m1)

```

`createNodeWithoutProperties2`:

```auto
(n1) -> (n2) -> (n3)

(n1)-> (m1)

```

Result by using the projections:  
`createNodeWithoutProperties1`:

```auto
(n1) 

```

`createNodeWithoutProperties2`:

```auto
(n1)-> (m1)

```

Excuse me for creating strange test cases...

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 12, 2022, 12:56pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/16 "2022-05-12T12:56:24Z")

</div>

No worries, I really appreciate how hard you try to "challenge" me. 😃  
It helps not only you but also the other users. But I need a little bit more input on this, I might miss something in my interpretation.

Given your projection:

```auto
public interface EntityWithOneLevelRelationshipProjection {
    Long getId();

    String getName();

    Map<String, String> getAdditionalProperties();

    Map<String, List<LinkWithoutTargetRelationshipProjection>> getRelationships();
}

```

This only mentions the `relationships` field. The `n1.setOtherRelationships` part will get ignored and as a consequence also the other relationships / nodes. Using `n1.setRelationships` with the right types, would do the magic.

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 12, 2022, 5:57pm UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/17 "2022-05-12T17:57:20Z")

</div>

Hi Gerrit,

Sorry for the late response. It took me some time trying to correct the reproducer. You are right, I made a mistake in my demo, I was a bit lost with the ugly variable names.

I have recreated other classes to make the demo clearer, since this time I don't think it's the problem of the projection. This time the problem happens even without projection but on the save.

You can find the a minimised demo here in the endpoint `createRootNode`: [https://github.com/Pandalei97/neo4jDemoBugRelationship/blob/main/src/main/java/com/example/demo/controller/RootNodeController.java](https://github.com/Pandalei97/neo4jDemoBugRelationship/blob/main/src/main/java/com/example/demo/controller/RootNodeController.java)

The classes used in the demo are :  
`RootNode`, `PropertyNode`, `SinglePropertyNode` and `MultiplePropertyNode`.

`SinglePropertyNode`, `MultiplePropertyNode` are inherited from `PropertyNode`.

Ideally, I should get a graphe  
 ![image](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/3X/3/b/3b8d7e16004aa1ff5e45d3ae9ec3c5f9b66ac575.png)

But with the reproducer, we've got  
 ![image](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/3X/4/9/49721ba0ed6843867084264995d4b90a252f0986.png)

There may be a problem in the management of the inheritance. Because if we move the property `name` from `PropertyNode` into `SinglePropertyNode` and `MultiplePropertyNode`, we will get the expected graphe.

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 13, 2022, 7:57am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/18 "2022-05-13T07:57:07Z")

</div>

The problem here is the data model (and Lombok providing a false safety feeling).  
You have to add `@EqualsAndHashCode(callSuper = true)` to the sub-classes `SinglePropertyNode` and `MultiPropertyNode`.  
As you have right observed, the behaviour changes when pushing `name` down to the child entities. This would make `@Data` consider them for `equals/hashCode`. But it does **not** include them per default, if they are part of the parent class.  
As a consequence, SDN will consider the `M2` as the very same object as `M1` and not persist `M2` at all. Of course when not even looking into `M2` it won't discover the connection to `S3`. (The outcome depends on the random order, the relationships are processed, sometimes it could also be that `M2` is first in the "cache" and `M1` is the skipped entity).

On a side note and before the question arises: I do not know the details, how Lombok processes the `Maps`. Given the fact that all `PropertyNodes` are the same, even a deep equals into the elements will evaluate to `true` because in the end, they only differ in their names.

---

<div class="post-metadata">

**Author:** ![pandalei97](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/pandalei97/32/23368_2.png) [@pandalei97](https://community.neo4j.com/u/pandalei97)\
**Post date:** [May 13, 2022, 8:53am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/19 "2022-05-13T08:53:29Z")

</div>

Yes, we should not rely too much on Lombok and we will take more care of the equator. Thanks for the detailed explications !

I have no more questions for the moment. I really appreciate our exchanges these days, I have really learned a lot ! 😃

---

<div class="post-metadata">

**Author:** ![gerrit.meier](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/gerrit.meier/32/27374_2.png) [@gerrit.meier](https://community.neo4j.com/u/gerrit.meier)\
**Post date:** [May 13, 2022, 10:28am UTC](https://community.neo4j.com/t/how-to-correctly-update-a-relationship/55682/20 "2022-05-13T10:28:10Z")

</div>

I can only second this. It is good to see people digging deep into the functionality we provide and find problems with corner cases.  
Fun fact: When I implemented the projections for the dynamic relationships on Wednesday, I also remembered why we have forbidden this in the first place and the flag `isDynamicRelationship` would not process.  
But now we have dropped Spring Data commons' strict `PropertyPath` at this place to be more flexible.  
Thanks a lot for your patience and detailed reports. 👏
