diff --git a/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java b/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java index 61635fa33..701d06b46 100644 --- a/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java +++ b/src/main/java/org/springframework/data/neo4j/core/Neo4jTemplate.java @@ -72,6 +72,7 @@ import org.springframework.data.neo4j.core.mapping.CypherGenerator; import org.springframework.data.neo4j.core.mapping.DtoInstantiatingConverter; import org.springframework.data.neo4j.core.mapping.EntityFromDtoInstantiatingConverter; import org.springframework.data.neo4j.core.mapping.EntityInstanceWithSource; +import org.springframework.data.neo4j.core.mapping.IdDescription; import org.springframework.data.neo4j.core.mapping.MappingSupport; import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.core.mapping.Neo4jPersistentEntity; @@ -978,7 +979,8 @@ public final class Neo4jTemplate implements @SuppressWarnings("unchecked") Map properties = (Map) tree.get(Constants.NAME_OF_PROPERTIES_PARAM); String idPropertyName = targetPersistentEntity.getIdProperty().getPropertyName(); - boolean assignedId = targetPersistentEntity.getIdDescription().isAssignedId(); + IdDescription idDescription = targetPersistentEntity.getIdDescription(); + boolean assignedId = idDescription.isAssignedId() || idDescription.isExternallyGeneratedId(); if (!includeProperty.isNotFiltering()) { properties.entrySet() .removeIf(e -> { diff --git a/src/main/java/org/springframework/data/neo4j/core/PropertyFilterSupport.java b/src/main/java/org/springframework/data/neo4j/core/PropertyFilterSupport.java index f3e30e18f..d3805bd32 100644 --- a/src/main/java/org/springframework/data/neo4j/core/PropertyFilterSupport.java +++ b/src/main/java/org/springframework/data/neo4j/core/PropertyFilterSupport.java @@ -146,8 +146,10 @@ public final class PropertyFilterSupport { TypeInformation typeInformation = currentTypeInformation.getProperty(nestedInputProperty.getName()); ProjectionPathProcessor nextProjectionPathProcessor = projectionPathProcessor.next(nestedInputProperty, typeInformation); - if (projectionPathProcessor.isChildLevel() && (domainType.equals(nextProjectionPathProcessor.typeInformation.getType()) - || returnedType.equals(nextProjectionPathProcessor.typeInformation.getType()))) { + if (projectionPathProcessor.isChildLevel() && + (domainType.equals(nextProjectionPathProcessor.typeInformation.getType()) + || returnedType.equals(nextProjectionPathProcessor.typeInformation.getActualType().getType()) + || returnedType.equals(nextProjectionPathProcessor.typeInformation.getType()))) { break; } diff --git a/src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java b/src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java index 5e567ed3f..1de28a94e 100644 --- a/src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java +++ b/src/main/java/org/springframework/data/neo4j/core/ReactiveNeo4jTemplate.java @@ -19,6 +19,7 @@ import static org.neo4j.cypherdsl.core.Cypher.anyNode; import static org.neo4j.cypherdsl.core.Cypher.asterisk; import static org.neo4j.cypherdsl.core.Cypher.parameter; +import org.springframework.data.neo4j.core.mapping.IdDescription; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -1068,7 +1069,8 @@ public final class ReactiveNeo4jTemplate implements @SuppressWarnings("unchecked") Function> binderFunction = neo4jMappingContext.getRequiredBinderFunctionFor(entityType); String idPropertyName = targetNodeDescription.getIdProperty().getPropertyName(); - boolean assignedId = targetNodeDescription.getIdDescription().isAssignedId(); + IdDescription idDescription = targetNodeDescription.getIdDescription(); + boolean assignedId = idDescription.isAssignedId() || idDescription.isExternallyGeneratedId(); binderFunction = binderFunction.andThen(tree -> { @SuppressWarnings("unchecked") Map properties = (Map) tree.get(Constants.NAME_OF_PROPERTIES_PARAM); diff --git a/src/main/java/org/springframework/data/neo4j/core/TemplateSupport.java b/src/main/java/org/springframework/data/neo4j/core/TemplateSupport.java index 673dd8ac3..87f66392e 100644 --- a/src/main/java/org/springframework/data/neo4j/core/TemplateSupport.java +++ b/src/main/java/org/springframework/data/neo4j/core/TemplateSupport.java @@ -44,6 +44,7 @@ import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.neo4j.core.mapping.Constants; import org.springframework.data.neo4j.core.mapping.EntityInstanceWithSource; +import org.springframework.data.neo4j.core.mapping.IdDescription; import org.springframework.data.neo4j.core.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.core.mapping.Neo4jPersistentEntity; import org.springframework.data.neo4j.core.mapping.Neo4jPersistentProperty; @@ -280,7 +281,8 @@ public final class TemplateSupport { Map properties = (Map) tree.get(Constants.NAME_OF_PROPERTIES_PARAM); String idPropertyName = entityMetaData.getIdProperty().getPropertyName(); - boolean assignedId = entityMetaData.getIdDescription().isAssignedId(); + IdDescription idDescription = entityMetaData.getIdDescription(); + boolean assignedId = idDescription.isAssignedId() || idDescription.isExternallyGeneratedId(); if (!includeProperty.isNotFiltering()) { properties.entrySet() .removeIf(e -> { diff --git a/src/test/java/org/springframework/data/neo4j/integration/movies/imperative/AdvancedMappingIT.java b/src/test/java/org/springframework/data/neo4j/integration/movies/imperative/AdvancedMappingIT.java index 71551f4d3..b259eb10a 100644 --- a/src/test/java/org/springframework/data/neo4j/integration/movies/imperative/AdvancedMappingIT.java +++ b/src/test/java/org/springframework/data/neo4j/integration/movies/imperative/AdvancedMappingIT.java @@ -132,6 +132,12 @@ class AdvancedMappingIT { Movie getSequel(); } + interface MovieWithMovieList { + String getTitle(); + + List getSequel(); + } + interface MovieRepository extends Neo4jRepository { MovieProjection findProjectionByTitle(String title); @@ -496,6 +502,19 @@ class AdvancedMappingIT { assertThat(movies.get(0).getActors()).hasSize(6); } + @Test // GH-2591 + void createPropertyFilterPathCorrectly(@Autowired Neo4jTemplate neo4jTemplate) { + Movie movie = new Movie("Test", "Movie"); + neo4jTemplate.saveAs(movie, MovieWithMovieList.class); + + Movie foundMovie = neo4jTemplate.findOne("MATCH (m:Movie{title:'Test'}) return m", Collections.emptyMap(), Movie.class).get(); + assertThat(foundMovie.getTitle()).isEqualTo("Test"); + assertThat(foundMovie.getDescription()).isNull(); + + // clean up to keep the other tests healthy + neo4jTemplate.deleteById("Test", Movie.class); + } + @Configuration @EnableTransactionManagement @EnableNeo4jRepositories(considerNestedRepositories = true)