diff --git a/pom.xml b/pom.xml index 87b7e95ebe..109046e2ef 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.0.DATAJDBC-417-SNAPSHOT pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index f2bbb72319..8e1d83721c 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.0.DATAJDBC-417-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index 0904eb8136..c476e012aa 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -5,7 +5,7 @@ 4.0.0 spring-data-jdbc - 1.2.0.BUILD-SNAPSHOT + 1.2.0.DATAJDBC-417-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.0.DATAJDBC-417-SNAPSHOT diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 1751c4244e..bc932dabf3 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -5,7 +5,7 @@ 4.0.0 spring-data-relational - 1.2.0.BUILD-SNAPSHOT + 1.2.0.DATAJDBC-417-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -13,7 +13,7 @@ org.springframework.data spring-data-relational-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.0.DATAJDBC-417-SNAPSHOT diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java index faca7bd195..ece16ad044 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java @@ -202,7 +202,8 @@ private List from(PersistentPropertyPath } else { - List pathNodes = nodesCache.get(path.getParentPath()); + List pathNodes = nodesCache.getOrDefault(path.getParentPath(), Collections.emptyList()); + pathNodes.forEach(parentNode -> { // todo: this should go into pathnode @@ -238,7 +239,17 @@ private boolean isDirectlyReferencedByRootIgnoringEmbeddables( @Nullable private Object getFromRootValue(PersistentPropertyPath path) { - return path.getBaseProperty().getOwner().getPropertyAccessor(entity).getProperty(path); + + if (path.getLength() == 0) + return entity; + + Object parent = getFromRootValue(path.getParentPath()); + if (parent == null) { + return null; + } + + return context.getRequiredPersistentEntity(parent.getClass()).getPropertyAccessor(parent) + .getProperty(path.getRequiredLeafProperty()); } private List createNodes(PersistentPropertyPath path, diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java index 3bf93eb38d..d66044d7d4 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java @@ -29,7 +29,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; - import org.springframework.data.annotation.Id; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.PersistentPropertyPaths; @@ -118,6 +117,7 @@ public void newEntityGetsConvertedToOneInsertByEmbeddedEntities() { ); } + @Test // DATAJDBC-112 public void newEntityWithReferenceGetsConvertedToTwoInserts() { @@ -530,6 +530,51 @@ public void multiLevelQualifiedReferencesWithOutId() { ); } + @Test // DATAJDBC-417 + public void savingANullEmbeddedWithEntity() { + + EmbeddedReferenceChainEntity entity = new EmbeddedReferenceChainEntity(null); + // the embedded is null !!! + + AggregateChange aggregateChange = // + new AggregateChange<>(Kind.SAVE, EmbeddedReferenceChainEntity.class, entity); + + converter.write(entity, aggregateChange); + + assertThat(aggregateChange.getActions()) // + .extracting(DbAction::getClass, // + DbAction::getEntityType, // + DbActionTestSupport::extractPath, // + DbActionTestSupport::actualEntityType, // + DbActionTestSupport::isWithDependsOn) // + .containsExactly( // + tuple(InsertRoot.class, EmbeddedReferenceChainEntity.class, "", EmbeddedReferenceChainEntity.class, false) // + ); + } + @Test // DATAJDBC-417 + public void savingInnerNullEmbeddedWithEntity() { + + RootWithEmbeddedReferenceChainEntity root = new RootWithEmbeddedReferenceChainEntity(null); + root.other = new EmbeddedReferenceChainEntity(null); + // the embedded is null !!! + + AggregateChange aggregateChange = // + new AggregateChange<>(Kind.SAVE, RootWithEmbeddedReferenceChainEntity.class, root); + + converter.write(root, aggregateChange); + + assertThat(aggregateChange.getActions()) // + .extracting(DbAction::getClass, // + DbAction::getEntityType, // + DbActionTestSupport::extractPath, // + DbActionTestSupport::actualEntityType, // + DbActionTestSupport::isWithDependsOn) // + .containsExactly( // + tuple(InsertRoot.class, RootWithEmbeddedReferenceChainEntity.class, "", RootWithEmbeddedReferenceChainEntity.class, false), // + tuple(Insert.class, EmbeddedReferenceChainEntity.class, "other", EmbeddedReferenceChainEntity.class, true) // + ); + } + private CascadingReferenceMiddleElement createMiddleElement(Element first, Element second) { CascadingReferenceMiddleElement middleElement1 = new CascadingReferenceMiddleElement(null); @@ -560,13 +605,6 @@ private Object getQualifier(DbAction a, PersistentPropertyPath path) { - - return a instanceof DbAction.WithDependingOn // - ? ((DbAction.WithDependingOn) a).getQualifiers().size() // - : 0; - } - static PersistentPropertyPath toPath(String path, Class source, RelationalMappingContext context) { @@ -592,6 +630,19 @@ static class EmbeddedReferenceEntity { @Embedded(onEmpty = OnEmpty.USE_NULL, prefix = "prefix_") Element other; } + @RequiredArgsConstructor + static class EmbeddedReferenceChainEntity { + + @Id final Long id; + @Embedded(onEmpty = OnEmpty.USE_NULL, prefix = "prefix_") ElementReference other; + } + @RequiredArgsConstructor + static class RootWithEmbeddedReferenceChainEntity { + + @Id final Long id; + EmbeddedReferenceChainEntity other; + } + @RequiredArgsConstructor static class ReferenceWoIdEntity { @@ -648,6 +699,11 @@ private static class Element { @Id final Long id; } + @RequiredArgsConstructor + private static class ElementReference { + final Element element; + } + @RequiredArgsConstructor private static class NoIdListMapContainer {