Skip to content

Commit f23071b

Browse files
committed
GH-2325 - Respect first level projection with SpEL.
1 parent f32a0ae commit f23071b

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

src/main/java/org/springframework/data/neo4j/core/PropertyFilterSupport.java

+12-10
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,18 @@ public static List<PropertyPath> getInputProperties(ResultProcessor resultProces
4444
List<PropertyPath> filteredProperties = new ArrayList<>();
4545

4646
boolean isProjecting = returnedType.isProjecting();
47+
boolean isClosedProjection = factory.getProjectionInformation(returnedType.getReturnedType()).isClosed();
48+
49+
if (!isProjecting || !isClosedProjection) {
50+
return Collections.emptyList();
51+
}
52+
4753
for (String inputProperty : returnedType.getInputProperties()) {
48-
if (isProjecting) {
49-
addPropertiesFrom(returnedType.getDomainType(), returnedType.getReturnedType(), factory,
50-
filteredProperties, inputProperty, mappingContext);
51-
} else {
52-
addPropertiesFromEntity(filteredProperties, PropertyPath.from(inputProperty, returnedType.getDomainType()),
53-
returnedType.getReturnedType(), mappingContext, new HashSet<>());
54-
}
54+
addPropertiesFrom(returnedType.getDomainType(), returnedType.getReturnedType(), factory,
55+
filteredProperties, inputProperty, mappingContext);
5556
}
56-
return isProjecting ? filteredProperties : Collections.emptyList();
57+
58+
return filteredProperties;
5759
}
5860

5961
public static List<PropertyPath> addPropertiesFrom(Class<?> returnType, Class<?> domainType,
@@ -161,11 +163,11 @@ private static void takeAllPropertiesFromEntity(Collection<PropertyPath> filtere
161163
filteredProperties.add(propertyPath);
162164

163165
persistentEntityFromProperty.doWithAll(neo4jPersistentProperty -> {
164-
addPropertiesFrom(filteredProperties, propertyPath.nested(neo4jPersistentProperty.getFieldName()), mappingContext, processedEntities);
166+
addPropertiesFromEntity(filteredProperties, propertyPath.nested(neo4jPersistentProperty.getFieldName()), mappingContext, processedEntities);
165167
});
166168
}
167169

168-
private static void addPropertiesFrom(Collection<PropertyPath> filteredProperties, PropertyPath propertyPath,
170+
private static void addPropertiesFromEntity(Collection<PropertyPath> filteredProperties, PropertyPath propertyPath,
169171
Neo4jMappingContext mappingContext,
170172
Collection<Neo4jPersistentEntity<?>> processedEntities) {
171173

src/test/java/org/springframework/data/neo4j/integration/imperative/ProjectionIT.java

+15
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
4949
import org.springframework.data.neo4j.integration.shared.common.NamesOnly;
5050
import org.springframework.data.neo4j.integration.shared.common.NamesOnlyDto;
51+
import org.springframework.data.neo4j.integration.shared.common.NamesWithSpELCity;
5152
import org.springframework.data.neo4j.integration.shared.common.Person;
5253
import org.springframework.data.neo4j.integration.shared.common.PersonSummary;
5354
import org.springframework.data.neo4j.integration.shared.common.ProjectionTest1O1;
@@ -143,6 +144,18 @@ void loadNamesOnlyProjection(@Autowired ProjectionPersonRepository repository) {
143144
assertThat(people).extracting(NamesOnly::getFullName).containsExactlyInAnyOrder(FIRST_NAME + " " + LAST_NAME, FIRST_NAME2 + " " + LAST_NAME);
144145
}
145146

147+
@Test // GH-2325
148+
void loadNamesWithCityProjection(@Autowired ProjectionPersonRepository repository) {
149+
150+
Collection<NamesWithSpELCity> people = repository.findProjectionByLastName(LAST_NAME);
151+
assertThat(people).hasSize(2);
152+
153+
assertThat(people).extracting(NamesWithSpELCity::getFirstName).containsExactlyInAnyOrder(FIRST_NAME, FIRST_NAME2);
154+
assertThat(people).extracting(NamesWithSpELCity::getLastName).containsOnly(LAST_NAME);
155+
156+
assertThat(people).extracting(NamesWithSpELCity::getCity).containsExactlyInAnyOrder(CITY, CITY);
157+
}
158+
146159
@Test
147160
void loadPersonSummaryProjection(@Autowired ProjectionPersonRepository repository) {
148161
Collection<PersonSummary> people = repository.findByFirstName(FIRST_NAME);
@@ -338,6 +351,8 @@ interface ProjectionPersonRepository extends Neo4jRepository<Person, Long>, Cyph
338351

339352
Collection<NamesOnly> findByLastName(String lastName);
340353

354+
Collection<NamesWithSpELCity> findProjectionByLastName(String lastName);
355+
341356
Page<NamesOnly> findAllProjectedBy(Pageable pageable);
342357

343358
Slice<NamesOnly> findSliceProjectedBy(Pageable pageable);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2011-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.neo4j.integration.shared.common;
17+
18+
import org.springframework.beans.factory.annotation.Value;
19+
20+
/**
21+
* @author Gerrit Meier
22+
*/
23+
public interface NamesWithSpELCity {
24+
25+
String getFirstName();
26+
27+
String getLastName();
28+
29+
@Value("#{target.address.city}")
30+
String getCity();
31+
}

0 commit comments

Comments
 (0)