You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Spring Data Neo4j 6.0.2 (actually the last version)
Spring Boot 2.4.1 (also the last version)
Spring WebFlux
Also tried using
Neo4J SDN/RX (The WebFlux Neo4j client for Spring data before officially merged in Spring Data)
Spring Boot 2.3.6.RELEASE
Spring WebFlux
I am facing an issue with duplicated relationships when same business Id is used on two entities of differents classes.
Steps to reproduce
Setup a project with Spring Data Neo4j, and a Neo4j database
Create two entities
@Node("Pol")
@Data
@With
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class PolEntity {
@Id
private String code;
@Relationship(type = RelationshipsNames.ROUTES)
private List<RouteProperties> routes = new ArrayList<>();
}
@Node("Pod")
@Data
@With
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class PodEntity {
@Id
private String code;
}
The RouteProperties class corresponds to the relationship between PolEntity and PolEntity, as following (pol:Pol)-[r:ROUTES]->(pod:Pod)
new PolEntity()
.withCode("TRMER")
.withRoutes(List.of(
new RouteProperties()
.withPod(new PodEntity()
.withCode("BEANR")
)
.withTruck(20),
// Other properties are optionals.
new RouteProperties()
.withPod(new PodEntity()
.withCode("TRMER") // Here is the duplicated, but for another kind of node.
)
.withTruck(20)
// Other properties are optionals.
));
Actual results
If I understand well, using @id with Spring Data Neo4j allows me to have the same Id on two entities, if they are not of the same class (ex Pol.code = 1 and Pod.code = 1).
And all is working when I am creating only nodes, without ROUTES relationships.
Using the debug, I can trace the requests performed by Spring Data Neo4j, and I see that the request is performed well on node creation
Pol creation (Id: TRMER)
MERGE (n:`Pol` {code: $__id__}) SET n = $__properties__ RETURN id(n)" {__id__="TRMER", __properties__={createdAt: NULL, code: "TRMER", lastModifiedAt: NULL, createdBy: NULL, lastModifiedBy: NULL}}
Pod creation (Id: BEANR)
MERGE (n:`Pod` {code: $__id__}) SET n = $__properties__ RETURN id(n)" {__id__="BEANR", __properties__={createdAt: NULL, code: "BEANR", lastModifiedAt: NULL, createdBy: NULL, lastModifiedBy: NULL}}
Pod creation with same Id as the Pol (Id: TRMER)
MERGE (n:`Pod` {code: $__id__}) SET n = $__properties__ RETURN id(n)" {__id__="TRMER", __properties__={createdAt: NULL, code: "TRMER", lastModifiedAt: NULL, createdBy: NULL, lastModifiedBy: NULL}}
But during the relationship creation, the request performed by the client is not what I'm waiting for (here I only show one example, the one with the duplication issue)
MATCH (startNode) WHERE startNode.code = $fromId MATCH (endNode) WHERE id(endNode) = 2283 MERGE (startNode)-[relProps:ROUTES]->(endNode) SET relProps = $__properties__" {fromId="TRMER", __properties__={ft20Currency: "EUR", ft40Currency: "EUR", truck: NULL, truckCurrency: NULL, ft40: 236.0, ft20: 618.0, ft40HC: 818.0, ft40HCCurrency: "EUR"}}
As you see here the request starts by : MATCH (startNode) WHERE startNode.code = $fromId.
Here is the problem, the generated request does not check the type of startNode, and so if I have a Poland a Pod with the same Id, there are two matches.
For the example, when $fromId = TRMER, the requests match Pol with TMRER code and Pod with TMRER code. It should only match the Pol (and surprisingly, the endNode match uses id function of cypher, using the unique auto generated id... so no problem for endNode, only for startNode)
As a consequence, in the graph, with this previous example, I have this structure
One Pol with TRMER code
Two Pod with TRMER and BEANR code
Two relationships (pol:Pol {code: 'TRMER')-[r:ROUTES]->(pod:Pod {code: 'BEANR'}) (pol:Pol {code: 'TRMER')-[r:ROUTES]->(pod:Pod {code: 'TRMER'})
And finally, a relationship I don't wan't, created because of the bug I'm describing (pod:Pod {code: 'TRMER')-[r:ROUTES]->(pod:Pod {code: 'BEANR'})
As a workaround, I can add a generated Id matching the auto generated Id in neo4j on those entities, to make them unique.
But I want to know if I'am doing something wrong?
Maybe I need to add some annotations?
Or maybe it is a bug in Spring Data Neo4j?
I think this MATCH (startNode) WHERE startNode.code = $fromId MATCH (endNode) WHERE id(endNode) = 2283
should be MATCH (startNode:Pol) WHERE startNode.code = $fromId MATCH (endNode:Pod) WHERE id(endNode) = 2283
The text was updated successfully, but these errors were encountered:
meistermeier
changed the title
Duplicated relationship when two nodes have same Ids, but with differents labels and classes
Link relationships by label and id if a non-generated id is used.
Jan 12, 2021
Copied from https://community.neo4j.com/t/spring-data-neo4j-duplicated-relationship-when-two-nodes-have-same-ids-but-with-differents-labels-and-classes/31898
Summary
Using
Spring Data Neo4j 6.0.2 (actually the last version)
Spring Boot 2.4.1 (also the last version)
Spring WebFlux
Also tried using
Neo4J SDN/RX (The WebFlux Neo4j client for Spring data before officially merged in Spring Data)
Spring Boot 2.3.6.RELEASE
Spring WebFlux
I am facing an issue with duplicated relationships when same business Id is used on two entities of differents classes.
Steps to reproduce
Setup a project with Spring Data Neo4j, and a Neo4j database
Create two entities
The RouteProperties class corresponds to the relationship between PolEntity and PolEntity, as following
(pol:Pol)-[r:ROUTES]->(pod:Pod)
Try to create the following PolEntity
Actual results
If I understand well, using @id with Spring Data Neo4j allows me to have the same Id on two entities, if they are not of the same class (ex Pol.code = 1 and Pod.code = 1).
And all is working when I am creating only nodes, without ROUTES relationships.
Using the debug, I can trace the requests performed by Spring Data Neo4j, and I see that the request is performed well on node creation
But during the relationship creation, the request performed by the client is not what I'm waiting for (here I only show one example, the one with the duplication issue)
Here is the problem, the generated request does not check the type of startNode, and so if I have a Poland a Pod with the same Id, there are two matches.
For the example, when $fromId = TRMER, the requests match Pol with TMRER code and Pod with TMRER code. It should only match the Pol (and surprisingly, the endNode match uses id function of cypher, using the unique auto generated id... so no problem for endNode, only for startNode)
As a consequence, in the graph, with this previous example, I have this structure
One Pol with TRMER code
Two Pod with TRMER and BEANR code
Two relationships
(pol:Pol {code: 'TRMER')-[r:ROUTES]->(pod:Pod {code: 'BEANR'})
(pol:Pol {code: 'TRMER')-[r:ROUTES]->(pod:Pod {code: 'TRMER'})
And finally, a relationship I don't wan't, created because of the bug I'm describing
(pod:Pod {code: 'TRMER')-[r:ROUTES]->(pod:Pod {code: 'BEANR'})
As a workaround, I can add a generated Id matching the auto generated Id in neo4j on those entities, to make them unique.
But I want to know if I'am doing something wrong?
Maybe I need to add some annotations?
Or maybe it is a bug in Spring Data Neo4j?
I think this
MATCH (startNode) WHERE startNode.code = $fromId MATCH (endNode) WHERE id(endNode) = 2283
should be
MATCH (startNode:Pol) WHERE startNode.code = $fromId MATCH (endNode:Pod) WHERE id(endNode) = 2283
The text was updated successfully, but these errors were encountered: