Skip to content

Commit

Permalink
GH-2591 - Fix StackOverflow on first level of recursive projections.
Browse files Browse the repository at this point in the history
Closes #2591
  • Loading branch information
meistermeier committed Sep 14, 2022
1 parent c050fc3 commit 402c0ba
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
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;
Expand Down Expand Up @@ -949,7 +950,8 @@ private Entity saveRelatedNode(Object entity, NodeDescription<?> targetNodeDescr
@SuppressWarnings("unchecked")
Map<String, Object> properties = (Map<String, Object>) 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 -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,10 @@ private static void addPropertiesFrom(Class<?> domainType, Class<?> returnedType
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
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;
Expand Down Expand Up @@ -1053,7 +1054,8 @@ private Mono<Entity> saveRelatedNode(Object relatedNode, Neo4jPersistentEntity<?
@SuppressWarnings("unchecked")
Function<Object, Map<String, Object>> 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<String, Object> properties = (Map<String, Object>) tree.get(Constants.NAME_OF_PROPERTIES_PARAM);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
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;
Expand Down Expand Up @@ -280,7 +281,8 @@ static <T> FilteredBinderFunction<T> createAndApplyPropertyFilter(
Map<String, Object> properties = (Map<String, Object>) 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 -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ interface MovieWithSequelEntity {
Movie getSequel();
}

interface MovieWithMovieList {
String getTitle();

List<MovieWithMovieList> getSequel();
}

interface MovieRepository extends Neo4jRepository<Movie, String> {

MovieProjection findProjectionByTitle(String title);
Expand Down Expand Up @@ -496,6 +502,19 @@ void mapPathWithMultipleSameTypeRelationships(@Autowired MovieRepository reposit
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)
Expand Down

0 comments on commit 402c0ba

Please sign in to comment.