|
25 | 25 | import java.util.Collections;
|
26 | 26 | import java.util.Comparator;
|
27 | 27 | import java.util.HashSet;
|
| 28 | +import java.util.IdentityHashMap; |
28 | 29 | import java.util.List;
|
29 | 30 | import java.util.Map;
|
| 31 | +import java.util.Objects; |
30 | 32 | import java.util.Set;
|
| 33 | +import java.util.TreeSet; |
31 | 34 | import java.util.UUID;
|
| 35 | +import java.util.stream.Collectors; |
32 | 36 |
|
33 | 37 | import org.assertj.core.api.Assertions;
|
34 | 38 | import org.junit.jupiter.api.Nested;
|
| 39 | +import org.junit.jupiter.api.RepeatedTest; |
35 | 40 | import org.junit.jupiter.api.Test;
|
36 | 41 | import org.junit.jupiter.api.extension.ExtendWith;
|
37 | 42 | import org.junit.jupiter.params.ParameterizedTest;
|
|
54 | 59 | import org.springframework.data.neo4j.core.mapping.datagraph1446.R2;
|
55 | 60 | import org.springframework.data.neo4j.core.mapping.datagraph1448.A_S3;
|
56 | 61 | import org.springframework.data.neo4j.core.mapping.datagraph1448.RelatedThing;
|
| 62 | +import org.springframework.data.neo4j.core.mapping.gh2574.Model; |
57 | 63 | import org.springframework.data.neo4j.core.schema.CompositeProperty;
|
58 | 64 | import org.springframework.data.neo4j.core.schema.GeneratedValue;
|
59 | 65 | import org.springframework.data.neo4j.core.schema.Id;
|
@@ -532,6 +538,60 @@ void dontFailOnCyclicRelationshipProperties() { // GH-2398
|
532 | 538 | assertThat(persistentEntity.getGraphProperties()).hasSize(3);
|
533 | 539 | }
|
534 | 540 |
|
| 541 | + private static Set<Class<?>> scanAndShuffle(String basePackage) throws ClassNotFoundException { |
| 542 | + |
| 543 | + Comparator<Class<?>> pseudoRandomComparator = new Comparator<Class<?>>() { |
| 544 | + private final Map<Object, UUID> uniqueIds = new IdentityHashMap<>(); |
| 545 | + |
| 546 | + @Override |
| 547 | + public int compare(Class<?> o1, Class<?> o2) { |
| 548 | + UUID e1 = uniqueIds.computeIfAbsent(o1, k -> UUID.randomUUID()); |
| 549 | + UUID e2 = uniqueIds.computeIfAbsent(o2, k -> UUID.randomUUID()); |
| 550 | + return e1.compareTo(e2); |
| 551 | + } |
| 552 | + }; |
| 553 | + |
| 554 | + Set<Class<?>> scanResult = Neo4jEntityScanner.get().scan(basePackage); |
| 555 | + Set<Class<?>> initialEntities = new TreeSet<>(pseudoRandomComparator); |
| 556 | + initialEntities.addAll(scanResult); |
| 557 | + return initialEntities; |
| 558 | + } |
| 559 | + |
| 560 | + |
| 561 | + @RepeatedTest(10) // GH-2574 |
| 562 | + void hierarchyMustBeConsistentlyReportedWithIntermediateConcreteClasses() throws ClassNotFoundException { |
| 563 | + |
| 564 | + Neo4jMappingContext neo4jMappingContext = new Neo4jMappingContext(); |
| 565 | + neo4jMappingContext.setStrict(true); |
| 566 | + neo4jMappingContext.setInitialEntitySet(scanAndShuffle("org.springframework.data.neo4j.core.mapping.gh2574")); |
| 567 | + neo4jMappingContext.initialize(); |
| 568 | + |
| 569 | + Neo4jPersistentEntity<?> b1 = Objects.requireNonNull(neo4jMappingContext.getPersistentEntity(Model.B1.class)); |
| 570 | + List<String> children = b1.getChildNodeDescriptionsInHierarchy() |
| 571 | + .stream().map(NodeDescription::getPrimaryLabel) |
| 572 | + .sorted() |
| 573 | + .collect(Collectors.toList()); |
| 574 | + |
| 575 | + assertThat(children).containsExactly("B2", "B2a", "B3", "B3a"); |
| 576 | + } |
| 577 | + |
| 578 | + @Test // GH-2574 |
| 579 | + void hierarchyMustBeConsistentlyReported() throws ClassNotFoundException { |
| 580 | + |
| 581 | + Neo4jMappingContext neo4jMappingContext = new Neo4jMappingContext(); |
| 582 | + neo4jMappingContext.setStrict(true); |
| 583 | + neo4jMappingContext.setInitialEntitySet(scanAndShuffle("org.springframework.data.neo4j.core.mapping.gh2574")); |
| 584 | + neo4jMappingContext.initialize(); |
| 585 | + |
| 586 | + Neo4jPersistentEntity<?> a1 = Objects.requireNonNull(neo4jMappingContext.getPersistentEntity(Model.A1.class)); |
| 587 | + List<String> children = a1.getChildNodeDescriptionsInHierarchy() |
| 588 | + .stream().map(NodeDescription::getPrimaryLabel) |
| 589 | + .sorted() |
| 590 | + .collect(Collectors.toList()); |
| 591 | + |
| 592 | + assertThat(children).containsExactly("A2", "A3", "A4"); |
| 593 | + } |
| 594 | + |
535 | 595 | static class DummyIdGenerator implements IdGenerator<Void> {
|
536 | 596 |
|
537 | 597 | @Override
|
|
0 commit comments