diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeUnitTests.java index 38087754..d9034e52 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeUnitTests.java @@ -41,12 +41,15 @@ public class AggregateChangeUnitTests { DummyEntity entity = new DummyEntity(); Content content = new Content(); + Tag tag = new Tag(); RelationalMappingContext context = new RelationalMappingContext(); RelationalConverter converter = new BasicRelationalConverter(context); PersistentPropertyAccessor propertyAccessor = context.getRequiredPersistentEntity(DummyEntity.class) .getPropertyAccessor(entity); + PersistentPropertyAccessor contentPropertyAccessor = context.getRequiredPersistentEntity(Content.class) + .getPropertyAccessor(content); Object id = 23; DbAction.WithEntity rootInsert = new DbAction.InsertRoot<>(entity); @@ -60,6 +63,12 @@ public class AggregateChangeUnitTests { return insert; } + DbAction.Insert createDeepInsert(String propertyName, Object value, Object key, DbAction.Insert parentInsert) { + DbAction.Insert insert = new DbAction.Insert<>(value, toPath(entity, value), parentInsert); + insert.getQualifiers().put(toPath(parentInsert.getPropertyPath().toDotPath() + "." + propertyName, DummyEntity.class), key); + return insert; + } + @Test // DATAJDBC-241 public void setIdForSimpleReference() { @@ -115,6 +124,99 @@ public class AggregateChangeUnitTests { .containsExactlyInAnyOrder(tuple("one", 23)); } + @Test // DATAJDBC-291 + public void setIdForDeepReference() { + + content.single = tag; + entity.single = content; + + DbAction.Insert parentInsert = createInsert("single", content, null); + DbAction.Insert insert = createDeepInsert("single", tag, null, parentInsert); + + AggregateChange.setIdOfNonRootEntity(context, converter, propertyAccessor, insert, id); + + Content result = contentPropertyAccessor.getBean(); + + assertThat(result.single.id).isEqualTo(id); + } + + @Test // DATAJDBC-291 + public void setIdForDeepReferenceElementList() { + + content.tagList.add(tag); + entity.single = content; + + DbAction.Insert parentInsert = createInsert("single", content, null); + DbAction.Insert insert = createDeepInsert("tagList", tag, 0, parentInsert); + + AggregateChange.setIdOfNonRootEntity(context, converter, propertyAccessor, insert, id); + + Content result = contentPropertyAccessor.getBean(); + assertThat(result.tagList).extracting(c -> c.id).containsExactlyInAnyOrder(23); + } + + @Test // DATAJDBC-291 + public void setIdForDeepElementSetElementSet() { + + content.tagSet.add(tag); + entity.contentSet.add(content); + + DbAction.Insert parentInsert = createInsert("contentSet", content, null); + DbAction.Insert insert = createDeepInsert("tagSet", tag, null, parentInsert); + + AggregateChange.setIdOfNonRootEntity(context, converter, propertyAccessor, insert, id); + + Content result = contentPropertyAccessor.getBean(); + assertThat(result.tagSet).isNotNull(); + assertThat(result.tagSet).extracting(c -> c == null ? "null" : c.id).containsExactlyInAnyOrder(23); + } + + @Test // DATAJDBC-291 + public void setIdForDeepElementListSingleReference() { + + content.single = tag; + entity.contentList.add(content); + + DbAction.Insert parentInsert = createInsert("contentList", content, 0); + DbAction.Insert insert = createDeepInsert("single", tag, null, parentInsert); + + AggregateChange.setIdOfNonRootEntity(context, converter, propertyAccessor, insert, id); + + Content result = contentPropertyAccessor.getBean(); + assertThat(result.single.id).isEqualTo(id); + } + + @Test // DATAJDBC-291 + public void setIdForDeepElementListElementList() { + + content.tagList.add(tag); + entity.contentList.add(content); + + DbAction.Insert parentInsert = createInsert("contentList", content, 0); + DbAction.Insert insert = createDeepInsert("tagList", tag, 0, parentInsert); + + AggregateChange.setIdOfNonRootEntity(context, converter, propertyAccessor, insert, id); + + Content result = contentPropertyAccessor.getBean(); + assertThat(result.tagList).extracting(c -> c.id).containsExactlyInAnyOrder(23); + } + + @Test // DATAJDBC-291 + public void setIdForDeepElementMapElementMap() { + + content.tagMap.put("one", tag); + entity.contentMap.put("one", content); + + DbAction.Insert parentInsert = createInsert("contentMap", content, "one"); + DbAction.Insert insert = createDeepInsert("tagMap", tag, "one", parentInsert); + + AggregateChange.setIdOfNonRootEntity(context, converter, propertyAccessor, insert, id); + + Content result = contentPropertyAccessor.getBean(); + assertThat(result.tagMap.entrySet()).extracting(e -> e.getKey(), e -> e.getValue().id) + .containsExactlyInAnyOrder(tuple("one", 23)); + } + PersistentPropertyPath toPath(String path, Class source) { PersistentPropertyPaths persistentPropertyPaths = context @@ -123,6 +225,15 @@ public class AggregateChangeUnitTests { return persistentPropertyPaths.filter(p -> p.toDotPath().equals(path)).stream().findFirst().orElse(null); } + PersistentPropertyPath toPath(DummyEntity root, Object pathValue) { + // DefaultPersistentPropertyPath is package-public + return new WritingContext(context, entity, new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, root)) + .insert().stream().filter(a -> a instanceof DbAction.Insert).map(DbAction.Insert.class::cast) + .filter(a -> a.getEntity() == pathValue) + .map(DbAction.Insert::getPropertyPath) + .findFirst().orElse(null); + } + private static class DummyEntity { @Id Integer rootId; @@ -139,5 +250,17 @@ public class AggregateChangeUnitTests { private static class Content { @Id Integer id; + + Tag single; + + Set tagSet = new HashSet<>(); + + List tagList = new ArrayList<>(); + + Map tagMap = new HashMap<>(); + } + + private static class Tag { + @Id Integer id; } }