Skip to content

Commit 4083c5d

Browse files
Compare dot paths for equality, not containg.
Fixes #2578 in which the mere presence of a fragment triggered inclusion of an otherwise excluded property.
1 parent 034c6e8 commit 4083c5d

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

src/main/java/org/springframework/data/neo4j/core/mapping/PropertyFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public boolean contains(String dotPath, Class<?> typeToCheck) {
111111

112112
//noinspection OptionalGetWithoutIsPresent
113113
return projectingPropertyPaths.stream().map(pp -> pp.propertyPath.toDotPath())
114-
.anyMatch(ppDotPath -> ppDotPath.contains(dotPath))
114+
.anyMatch(ppDotPath -> ppDotPath.equals(dotPath))
115115
|| (dotPath.contains(".") && candidate.isPresent() &&
116116
projectingPropertyPaths.stream()
117117
.filter(pp -> pp.propertyPath.toDotPath().equals(candidate.get())).findFirst().get().isEntity);

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import java.util.ArrayList;
2222
import java.util.Collection;
2323
import java.util.Collections;
24+
import java.util.HashSet;
2425
import java.util.List;
2526
import java.util.Map;
2627
import java.util.Optional;
28+
import java.util.Set;
2729

2830
import org.junit.jupiter.api.BeforeEach;
2931
import org.junit.jupiter.api.Test;
@@ -45,6 +47,8 @@
4547
import org.springframework.data.domain.Pageable;
4648
import org.springframework.data.domain.Slice;
4749
import org.springframework.data.domain.Sort;
50+
import org.springframework.data.neo4j.core.Neo4jOperations;
51+
import org.springframework.data.neo4j.integration.shared.common.DoritoEatingPerson;
4852
import org.springframework.data.neo4j.test.Neo4jImperativeTestConfiguration;
4953
import org.springframework.data.neo4j.core.DatabaseSelectionProvider;
5054
import org.springframework.data.neo4j.core.Neo4jTemplate;
@@ -423,6 +427,38 @@ void saveWithCustomPropertyNameWorks(@Autowired Neo4jTemplate neo4jTemplate) {
423427
}
424428
}
425429

430+
@Test // GH-2578
431+
public void projectionRespectedWithInexactPropertyNameMatch(@Autowired Neo4jOperations neo4jOperations) {
432+
final DoritoEatingPerson person = new DoritoEatingPerson("Bob");
433+
person.setEatsDoritos(true);
434+
person.setFriendsAlsoEatDoritos(true);
435+
Set<DoritoEatingPerson> friends = new HashSet<>();
436+
friends.add(new DoritoEatingPerson("Alice"));
437+
friends.add(new DoritoEatingPerson("Zoey"));
438+
person.setFriends(friends);
439+
440+
neo4jOperations.saveAs(person, DoritoEatingPerson.PropertiesProjection1.class);
441+
442+
final Optional<DoritoEatingPerson> saved = neo4jOperations.findById(person.getId(), DoritoEatingPerson.class);
443+
assertThat(saved).hasValueSatisfying(it -> assertThat(it.getFriends()).isEmpty());
444+
}
445+
446+
@Test // GH-2578
447+
public void projectionRespected(@Autowired Neo4jOperations neo4jOperations) {
448+
final DoritoEatingPerson person = new DoritoEatingPerson("Ben");
449+
person.setEatsDoritos(true);
450+
person.setFriendsAlsoEatDoritos(true);
451+
Set<DoritoEatingPerson> friends = new HashSet<>();
452+
friends.add(new DoritoEatingPerson("Kid"));
453+
friends.add(new DoritoEatingPerson("Jeremias"));
454+
person.setFriends(friends);
455+
456+
neo4jOperations.saveAs(person, DoritoEatingPerson.PropertiesProjection2.class);
457+
458+
final Optional<DoritoEatingPerson> saved = neo4jOperations.findById(person.getId(), DoritoEatingPerson.class);
459+
assertThat(saved).hasValueSatisfying(it -> assertThat(it.getFriends()).isEmpty());
460+
}
461+
426462
private static void projectedEntities(PersonDepartmentQueryResult personAndDepartment) {
427463
assertThat(personAndDepartment.getPerson()).extracting(PersonEntity::getId).isEqualTo("p1");
428464
assertThat(personAndDepartment.getPerson()).extracting(PersonEntity::getEmail).isEqualTo("[email protected]");
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2011-2022 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 lombok.AllArgsConstructor;
19+
import lombok.Data;
20+
import lombok.NoArgsConstructor;
21+
import lombok.ToString;
22+
23+
import java.util.HashSet;
24+
import java.util.Set;
25+
26+
import org.springframework.data.neo4j.core.schema.Id;
27+
import org.springframework.data.neo4j.core.schema.Node;
28+
import org.springframework.data.neo4j.core.schema.Property;
29+
import org.springframework.data.neo4j.core.schema.Relationship;
30+
31+
/**
32+
* @author Michael J. Simons
33+
*/
34+
@Data
35+
@ToString(exclude = { "friends" })
36+
@Node
37+
@NoArgsConstructor
38+
@AllArgsConstructor
39+
public class DoritoEatingPerson {
40+
41+
@Id
42+
private long id;
43+
44+
@Property
45+
private String name;
46+
47+
@Property
48+
private boolean eatsDoritos;
49+
50+
@Property
51+
private boolean friendsAlsoEatDoritos;
52+
53+
@Relationship
54+
private Set<DoritoEatingPerson> friends = new HashSet<>();
55+
56+
public DoritoEatingPerson(String name) {
57+
this.name = name;
58+
}
59+
60+
/**
61+
* Projection containing ambiguous name
62+
*/
63+
public interface PropertiesProjection1 {
64+
65+
boolean getEatsDoritos();
66+
67+
boolean getFriendsAlsoEatDoritos();
68+
}
69+
70+
/**
71+
* Projection not containing ambiguous name
72+
*/
73+
public interface PropertiesProjection2 {
74+
75+
boolean getEatsDoritos();
76+
}
77+
}

0 commit comments

Comments
 (0)