spring-projects / spring-data-neo4j

Provide support to increase developer productivity in Java when using Neo4j. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
http://spring.io/projects/spring-data-neo4j
Apache License 2.0
835 stars 618 forks source link

[BUG] Multi Relationships cannot get right conversion #2973

Open yangyaofei opened 4 days ago

yangyaofei commented 4 days ago

If I have a BaseNode with Map type relationships defined with a base class

@Node
public class BaseNode {
    @Id
    @GeneratedValue
    private UUID id;

    @Relationship(direction = Relationship.Direction.OUTGOING)
    private Map<String, List<BaseRelationship>> relationships = new HashMap<>();
}

@RelationshipProperties
public abstract class BaseRelationship {
    @RelationshipId
    @GeneratedValue
    private Long id;
    @TargetNode
    private BaseNode targetNode;
}

And I have two real class for relationship:

@RelationshipProperties
public class Relationship extend BaseRelationship{

}

@RelationshipProperties
public class AnotherRelationship extend BaseRelationship{

}

If there is a BaseNode with both two relationships :

var node = new BaseNode();
node.setRelationships(Map.of(
    "relation", List.of(
        new Relationship(), new AnotherRelationship()
    )
))
baseNodeRepository.save(node)
// the node and relations store in neo4j is good with clear type

Since SDN in node can get right instance, I think the relationship will get right, but the code below, the relationships will get same type of instance, both the Relationship or AnotherRelationship, cannot Get Proper type.

var node = baseNodeRepository.findById(id);
List<BaseRelationship> relationships = node.getRelationships().get("relation");
yangyaofei commented 4 days ago

I dig into the code, I found in DefaultNeo4jEntityConverter, In getLabels and map function, I think SDN use labels to get the type of node and relationship, but relationship don't have a label, it has type.

So, the getLabels function cannot get type information with relationship (always get BaseRelationship), and this cause this bug I think.

https://github.com/spring-projects/spring-data-neo4j/blob/f10c95f8fbb1428a60e0e254b10da94474653994/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java#L435

https://github.com/spring-projects/spring-data-neo4j/blob/f10c95f8fbb1428a60e0e254b10da94474653994/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java#L317

I think, it should add few code in getLabels like this line: https://github.com/spring-projects/spring-data-neo4j/blob/f10c95f8fbb1428a60e0e254b10da94474653994/src/main/java/org/springframework/data/neo4j/core/mapping/DefaultNeo4jEntityConverter.java#L440

add code below can solve this bug:

 else if (queryResult instanceof Relationship) {
    Relationship relationshipRepresentation = (Relationship) queryResult;
    labels.add(relationshipRepresentation.type());
}