Skip to content

Commit 2ba67cb

Browse files
fix: Look for static labels to contain a label, not vice versa. (#2887)
Fixes #2886.
1 parent 2d3f3f8 commit 2ba67cb

File tree

8 files changed

+218
-4
lines changed

8 files changed

+218
-4
lines changed

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

+7
Original file line numberDiff line numberDiff line change
@@ -620,4 +620,11 @@ private boolean calculatePossibleCircles(NodeDescription<?> nodeDescription, Set
620620
visitedNodes.addAll(visitedTargetNodes);
621621
return false;
622622
}
623+
624+
@Override
625+
public String toString() {
626+
return "DefaultNeo4jPersistentEntity{" +
627+
"primaryLabel='" + primaryLabel + '\'' +
628+
'}';
629+
}
623630
}

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public NodeDescriptionAndLabels deriveConcreteNodeDescription(NodeDescription<?>
102102
return nodeDescriptionAndLabels.apply(entityDescription, labels);
103103
}
104104

105-
private NodeDescriptionAndLabels computeConcreteNodeDescription(NodeDescription<?> entityDescription, List<String> labels) {
105+
private NodeDescriptionAndLabels computeConcreteNodeDescription(NodeDescription<?> entityDescription, @Nullable List<String> labels) {
106106

107107
boolean isConcreteClassThatFulfillsEverything = !Modifier.isAbstract(entityDescription.getUnderlyingClass().getModifiers()) && entityDescription.getStaticLabels().containsAll(labels);
108108

@@ -139,9 +139,9 @@ private NodeDescriptionAndLabels computeConcreteNodeDescription(NodeDescription<
139139

140140
int unmatchedLabelsCount = 0;
141141
List<String> matchingLabels = new ArrayList<>();
142-
for (String staticLabel : staticLabels) {
143-
if (labels.contains(staticLabel)) {
144-
matchingLabels.add(staticLabel);
142+
for (String label : labels) {
143+
if (staticLabels.contains(label)) {
144+
matchingLabels.add(label);
145145
} else {
146146
unmatchedLabelsCount++;
147147
}

src/test/java/org/springframework/data/neo4j/integration/issues/IssuesIT.java

+30
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.List;
2929
import java.util.Map;
3030
import java.util.Optional;
31+
import java.util.Set;
3132
import java.util.stream.Collectors;
3233

3334
import org.assertj.core.api.InstanceOfAssertFactories;
@@ -144,6 +145,9 @@
144145
import org.springframework.data.neo4j.integration.issues.gh2639.Sales;
145146
import org.springframework.data.neo4j.integration.issues.gh2819.GH2819Model;
146147
import org.springframework.data.neo4j.integration.issues.gh2819.GH2819Repository;
148+
import org.springframework.data.neo4j.integration.issues.gh2886.Apple;
149+
import org.springframework.data.neo4j.integration.issues.gh2886.FruitRepository;
150+
import org.springframework.data.neo4j.integration.issues.gh2886.Orange;
147151
import org.springframework.data.neo4j.integration.issues.qbe.A;
148152
import org.springframework.data.neo4j.integration.issues.qbe.ARepository;
149153
import org.springframework.data.neo4j.integration.issues.qbe.B;
@@ -1051,6 +1055,32 @@ void inheritanceAndProjectionShouldMapRelatedNodesCorrectly(@Autowired GH2819Rep
10511055

10521056
}
10531057

1058+
@Test
1059+
@Tag("GH-2886")
1060+
void dynamicLabels(@Autowired FruitRepository repository) {
1061+
1062+
var f1 = new Apple();
1063+
f1.setVolume(1.0);
1064+
f1.setColor("Red");
1065+
f1.setLabels(Set.of("X"));
1066+
1067+
var f2 = new Apple();
1068+
f2.setColor("Blue");
1069+
1070+
var f3 = new Orange();
1071+
f2.setVolume(3.0);
1072+
f3.setColor("Red");
1073+
f3.setLabels(Set.of("Y"));
1074+
1075+
var f4 = new Orange();
1076+
f4.setColor("Yellow");
1077+
1078+
repository.saveAll(List.of(f1, f2, f3, f4));
1079+
1080+
var fruits = repository.findAllFruits();
1081+
assertThat(fruits).allMatch(f -> f instanceof Apple || f instanceof Orange);
1082+
}
1083+
10541084
@Configuration
10551085
@EnableTransactionManagement
10561086
@EnableNeo4jRepositories(namedQueriesLocation = "more-custom-queries.properties")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2011-2024 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.issues.gh2886;
17+
18+
import org.springframework.data.neo4j.core.schema.Node;
19+
20+
/**
21+
* GH-2886
22+
*/
23+
@Node(primaryLabel = "Apple")
24+
public class Apple extends MagicalFruit {
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2011-2024 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.issues.gh2886;
17+
18+
import java.util.Set;
19+
20+
import org.springframework.data.neo4j.core.schema.DynamicLabels;
21+
import org.springframework.data.neo4j.core.schema.Id;
22+
import org.springframework.data.neo4j.core.schema.Node;
23+
24+
/**
25+
* GH-2886
26+
*/
27+
@Node(primaryLabel = "Fruit")
28+
public abstract class Fruit {
29+
30+
@Id
31+
protected String id;
32+
33+
@DynamicLabels
34+
protected Set<String> labels = Set.of();
35+
36+
public String getId() {
37+
return this.id;
38+
}
39+
40+
public Set<String> getLabels() {
41+
return this.labels;
42+
}
43+
44+
public void setId(String id) {
45+
this.id = id;
46+
}
47+
48+
public void setLabels(Set<String> labels) {
49+
this.labels = labels;
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2011-2024 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.issues.gh2886;
17+
18+
import java.util.List;
19+
20+
import org.springframework.data.neo4j.repository.Neo4jRepository;
21+
import org.springframework.data.neo4j.repository.query.Query;
22+
import org.springframework.stereotype.Repository;
23+
24+
/**
25+
* GH-2886
26+
*/
27+
@Repository
28+
public interface FruitRepository extends Neo4jRepository<Fruit, String> {
29+
@Query("MATCH (f:Fruit) RETURN f")
30+
List<Fruit> findAllFruits();
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2011-2024 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.issues.gh2886;
17+
18+
import org.springframework.data.neo4j.core.schema.Node;
19+
20+
/**
21+
* GH-2886
22+
*/
23+
@Node(primaryLabel = "MagicalFruit")
24+
public class MagicalFruit extends Fruit {
25+
26+
private double volume;
27+
28+
private String color;
29+
30+
public double getVolume() {
31+
return this.volume;
32+
}
33+
34+
public String getColor() {
35+
return this.color;
36+
}
37+
38+
public void setVolume(double volume) {
39+
this.volume = volume;
40+
}
41+
42+
public void setColor(String color) {
43+
this.color = color;
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2011-2024 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.issues.gh2886;
17+
18+
import org.springframework.data.neo4j.core.schema.Node;
19+
20+
/**
21+
* GH-2886
22+
*/
23+
@Node(primaryLabel = "Orange")
24+
public class Orange extends MagicalFruit {
25+
}

0 commit comments

Comments
 (0)