|
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;
|
@@ -592,6 +598,59 @@ void shouldInvokePostLoadInKotlinClassesByDelegate() {
|
592 | 598 | assertThat(instance.getBaseName()).isEqualTo("someValue");
|
593 | 599 | }
|
594 | 600 |
|
| 601 | + private static Set<Class<?>> scanAndShuffle(String basePackage) throws ClassNotFoundException { |
| 602 | + |
| 603 | + Comparator<Class<?>> pseudoRandomComparator = new Comparator<Class<?>>() { |
| 604 | + private final Map<Object, UUID> uniqueIds = new IdentityHashMap<>(); |
| 605 | + |
| 606 | + @Override |
| 607 | + public int compare(Class<?> o1, Class<?> o2) { |
| 608 | + UUID e1 = uniqueIds.computeIfAbsent(o1, k -> UUID.randomUUID()); |
| 609 | + UUID e2 = uniqueIds.computeIfAbsent(o2, k -> UUID.randomUUID()); |
| 610 | + return e1.compareTo(e2); |
| 611 | + } |
| 612 | + }; |
| 613 | + |
| 614 | + Set<Class<?>> scanResult = Neo4jEntityScanner.get().scan(basePackage); |
| 615 | + Set<Class<?>> initialEntities = new TreeSet<>(pseudoRandomComparator); |
| 616 | + initialEntities.addAll(scanResult); |
| 617 | + return initialEntities; |
| 618 | + } |
| 619 | + |
| 620 | + @RepeatedTest(10) // GH-2574 |
| 621 | + void hierarchyMustBeConsistentlyReportedWithIntermediateConcreteClasses() throws ClassNotFoundException { |
| 622 | + |
| 623 | + Neo4jMappingContext neo4jMappingContext = new Neo4jMappingContext(); |
| 624 | + neo4jMappingContext.setStrict(true); |
| 625 | + neo4jMappingContext.setInitialEntitySet(scanAndShuffle("org.springframework.data.neo4j.core.mapping.gh2574")); |
| 626 | + neo4jMappingContext.initialize(); |
| 627 | + |
| 628 | + Neo4jPersistentEntity<?> b1 = Objects.requireNonNull(neo4jMappingContext.getPersistentEntity(Model.B1.class)); |
| 629 | + List<String> children = b1.getChildNodeDescriptionsInHierarchy() |
| 630 | + .stream().map(NodeDescription::getPrimaryLabel) |
| 631 | + .sorted() |
| 632 | + .collect(Collectors.toList()); |
| 633 | + |
| 634 | + assertThat(children).containsExactly("B2", "B2a", "B3", "B3a"); |
| 635 | + } |
| 636 | + |
| 637 | + @Test // GH-2574 |
| 638 | + void hierarchyMustBeConsistentlyReported() throws ClassNotFoundException { |
| 639 | + |
| 640 | + Neo4jMappingContext neo4jMappingContext = new Neo4jMappingContext(); |
| 641 | + neo4jMappingContext.setStrict(true); |
| 642 | + neo4jMappingContext.setInitialEntitySet(scanAndShuffle("org.springframework.data.neo4j.core.mapping.gh2574")); |
| 643 | + neo4jMappingContext.initialize(); |
| 644 | + |
| 645 | + Neo4jPersistentEntity<?> a1 = Objects.requireNonNull(neo4jMappingContext.getPersistentEntity(Model.A1.class)); |
| 646 | + List<String> children = a1.getChildNodeDescriptionsInHierarchy() |
| 647 | + .stream().map(NodeDescription::getPrimaryLabel) |
| 648 | + .sorted() |
| 649 | + .collect(Collectors.toList()); |
| 650 | + |
| 651 | + assertThat(children).containsExactly("A2", "A3", "A4"); |
| 652 | + } |
| 653 | + |
595 | 654 | static class EntityWithPostLoadMethods {
|
596 | 655 |
|
597 | 656 | String m1;
|
|
0 commit comments