From 018d1d5d43f1612336a1d332d7660478e087996e Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Wed, 22 Nov 2023 13:27:20 +0100 Subject: [PATCH] GH-2828 - Use correct node name related node in find by example. Closes #2828 --- .../neo4j/core/mapping/IdDescription.java | 19 +++++++++++++++++++ .../neo4j/core/mapping/NodeDescription.java | 3 +++ .../neo4j/repository/query/Predicate.java | 2 +- .../integration/imperative/RepositoryIT.java | 5 ++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java b/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java index bc2c96041..a8c8208e9 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/IdDescription.java @@ -52,6 +52,7 @@ public final class IdDescription { * The property that stores the id if applicable. */ private @Nullable final String graphPropertyName; + private final boolean isDeprecated; private final Lazy idExpression; @@ -93,6 +94,7 @@ private IdDescription(SymbolicName symbolicName, @Nullable Class { final Node rootNode = Cypher.anyNode(symbolicName); @@ -109,6 +111,23 @@ public Expression asIdExpression() { return this.idExpression.get(); } + /** + * Creates the right identifier expression for this node entity. + * Note: This enforces a recalculation of the name on invoke. + * + * @param nodeName use this name as the symbolic name of the node in the query + * @return An expression that represents the right identifier type. + */ + public Expression asIdExpression(String nodeName) { + final Node rootNode = Cypher.anyNode(nodeName); + if (this.isInternallyGeneratedId()) { + return isDeprecated ? Functions.id(rootNode) : Functions.elementId(rootNode); + } else { + return this.getOptionalGraphPropertyName() + .map(propertyName -> Cypher.property(nodeName, propertyName)).get(); + } + } + public Optional>> getIdGeneratorClass() { return Optional.ofNullable(idGeneratorClass); } diff --git a/src/main/java/org/springframework/data/neo4j/core/mapping/NodeDescription.java b/src/main/java/org/springframework/data/neo4j/core/mapping/NodeDescription.java index b03690b19..fccb46411 100644 --- a/src/main/java/org/springframework/data/neo4j/core/mapping/NodeDescription.java +++ b/src/main/java/org/springframework/data/neo4j/core/mapping/NodeDescription.java @@ -136,6 +136,9 @@ default boolean isUsingInternalIds() { NodeDescription getParentNodeDescription(); /** + * Creates the right identifier expression for this node entity. + * Note: The expression gets cached and won't get recalculated at every invocation. + * * @return An expression that represents the right identifier type. */ default Expression getIdExpression() { diff --git a/src/main/java/org/springframework/data/neo4j/repository/query/Predicate.java b/src/main/java/org/springframework/data/neo4j/repository/query/Predicate.java index 09432790f..9c9c411db 100644 --- a/src/main/java/org/springframework/data/neo4j/repository/query/Predicate.java +++ b/src/main/java/org/springframework/data/neo4j/repository/query/Predicate.java @@ -167,7 +167,7 @@ private static void addConditionAndParameters(Neo4jMappingContext mappingContext if (isRootNode) { condition = predicate.neo4jPersistentEntity.getIdExpression().isEqualTo(literalOf(theValue)); } else { - condition = nodeDescription.getIdExpression().isEqualTo(literalOf(theValue)); + condition = nodeDescription.getIdDescription().asIdExpression(wrapper.getNodeName()).isEqualTo(literalOf(theValue)); } } else { Expression property = !isRootNode ? property(wrapper.getNodeName(), propertyName) : property(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription), propertyName); diff --git a/src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryIT.java b/src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryIT.java index 4471571e7..e7674325d 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/imperative/RepositoryIT.java @@ -3118,7 +3118,10 @@ void findEntityWithRelationshipByFindOneByExample(@Autowired RelationshipReposit long petNode2Id = TestIdentitySupport.getInternalId(petNode2); PersonWithRelationship probe = new PersonWithRelationship(); - probe.setName("Freddie"); + Hobby hobbies = new Hobby(); + hobbies.setId(hobbyNodeId); + hobbies.setName("Music"); + probe.setHobbies(hobbies); PersonWithRelationship loadedPerson = repository.findOne(Example.of(probe)).get(); assertThat(loadedPerson.getName()).isEqualTo("Freddie"); assertThat(loadedPerson.getId()).isEqualTo(personId);