diff --git a/pom.xml b/pom.xml
index b293417702..16d92e7a35 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-jdbc
- 1.0.0.BUILD-SNAPSHOT
+ 1.0.0.DATAJDBC-188-SNAPSHOT
Spring Data JDBC
Spring Data module for JDBC repositories.
diff --git a/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java b/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java
index fb8c972a30..7b6af0de45 100644
--- a/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java
+++ b/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java
@@ -94,6 +94,10 @@ public void setSimpleTypeHolder(SimpleTypeHolder simpleTypes) {
this.simpleTypeHolder = simpleTypes;
}
+ /**
+ * returns all {@link PropertyPath}s reachable from the root type in the order needed for deleting, i.e. the deepest
+ * reference first.
+ */
public List referencedEntities(Class> rootType, PropertyPath path) {
List paths = new ArrayList<>();
diff --git a/src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityDeleteWriterUnitTests.java b/src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityDeleteWriterUnitTests.java
index beed915955..cc6adfdab4 100644
--- a/src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityDeleteWriterUnitTests.java
+++ b/src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityDeleteWriterUnitTests.java
@@ -25,6 +25,7 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.conversion.AggregateChange.Kind;
import org.springframework.data.jdbc.core.conversion.DbAction.Delete;
+import org.springframework.data.jdbc.core.conversion.DbAction.DeleteAll;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
/**
@@ -37,21 +38,46 @@ public class JdbcEntityDeleteWriterUnitTests {
JdbcEntityDeleteWriter converter = new JdbcEntityDeleteWriter(new JdbcMappingContext());
- @Test
+ private static Object dotPath(DbAction dba) {
+
+ JdbcPropertyPath propertyPath = dba.getPropertyPath();
+ return propertyPath == null ? null : propertyPath.toDotPath();
+ }
+
+ @Test // DATAJDBC-112
public void deleteDeletesTheEntityAndReferencedEntities() {
SomeEntity entity = new SomeEntity(23L);
AggregateChange aggregateChange = new AggregateChange<>(Kind.DELETE, SomeEntity.class, entity);
- converter.write(entity, aggregateChange);
+ converter.write(entity.id, aggregateChange);
+
+ Assertions.assertThat(aggregateChange.getActions())
+ .extracting(DbAction::getClass, DbAction::getEntityType, JdbcEntityDeleteWriterUnitTests::dotPath) //
+ .containsExactly( //
+ Tuple.tuple(Delete.class, YetAnother.class, "other.yetAnother"), //
+ Tuple.tuple(Delete.class, OtherEntity.class, "other"), //
+ Tuple.tuple(Delete.class, SomeEntity.class, null) //
+ );
+ }
+
+ @Test // DATAJDBC-188
+ public void deleteAllDeletesAllEntitiesAndReferencedEntities() {
+
+ SomeEntity entity = new SomeEntity(23L);
+
+ AggregateChange aggregateChange = new AggregateChange(Kind.DELETE, SomeEntity.class, null);
+
+ converter.write(null, aggregateChange);
- Assertions.assertThat(aggregateChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType)
+ Assertions.assertThat(aggregateChange.getActions())
+ .extracting(DbAction::getClass, DbAction::getEntityType, JdbcEntityDeleteWriterUnitTests::dotPath) //
.containsExactly( //
- Tuple.tuple(Delete.class, YetAnother.class), //
- Tuple.tuple(Delete.class, OtherEntity.class), //
- Tuple.tuple(Delete.class, SomeEntity.class) //
- );
+ Tuple.tuple(DeleteAll.class, YetAnother.class, "other.yetAnother"), //
+ Tuple.tuple(DeleteAll.class, OtherEntity.class, "other"), //
+ Tuple.tuple(DeleteAll.class, SomeEntity.class, null) //
+ );
}
@Data
diff --git a/src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterUnitTests.java b/src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterUnitTests.java
index 8acb5c14b8..b86e2ae2a5 100644
--- a/src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterUnitTests.java
+++ b/src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterUnitTests.java
@@ -32,6 +32,7 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.conversion.AggregateChange.Kind;
import org.springframework.data.jdbc.core.conversion.DbAction.Delete;
+import org.springframework.data.jdbc.core.conversion.DbAction.DeleteAll;
import org.springframework.data.jdbc.core.conversion.DbAction.Insert;
import org.springframework.data.jdbc.core.conversion.DbAction.Update;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
@@ -163,6 +164,39 @@ public void cascadingReferencesTriggerCascadingActions() {
);
}
+ @Test // DATAJDBC-188
+ public void cascadingReferencesTriggerCascadingActionsForUpdate() {
+
+ CascadingReferenceEntity entity = new CascadingReferenceEntity(23L);
+
+ entity.other.add(createMiddleElement( //
+ new Element(null), //
+ new Element(null)) //
+ );
+
+ entity.other.add(createMiddleElement( //
+ new Element(null), //
+ new Element(null)) //
+ );
+
+ AggregateChange aggregateChange = new AggregateChange(Kind.SAVE, CascadingReferenceEntity.class, entity);
+
+ converter.write(entity, aggregateChange);
+
+ assertThat(aggregateChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType, this::extractPath) //
+ .containsExactly( //
+ tuple(Delete.class, Element.class, "other.element"),
+ tuple(Delete.class, CascadingReferenceMiddleElement.class, "other"),
+ tuple(Update.class, CascadingReferenceEntity.class, ""), //
+ tuple(Insert.class, CascadingReferenceMiddleElement.class, "other"), //
+ tuple(Insert.class, Element.class, "other.element"), //
+ tuple(Insert.class, Element.class, "other.element"), //
+ tuple(Insert.class, CascadingReferenceMiddleElement.class, "other"), //
+ tuple(Insert.class, Element.class, "other.element"), //
+ tuple(Insert.class, Element.class, "other.element") //
+ );
+ }
+
@Test // DATAJDBC-131
public void newEntityWithEmptyMapResultsInSingleInsert() {
diff --git a/src/test/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContextUnitTests.java b/src/test/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContextUnitTests.java
new file mode 100644
index 0000000000..0d25f840ba
--- /dev/null
+++ b/src/test/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContextUnitTests.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.jdbc.mapping.model;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Test;
+import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
+import org.springframework.data.mapping.PropertyPath;
+
+/**
+ * @author Jens Schauder
+ */
+public class JdbcMappingContextUnitTests {
+
+ JdbcMappingContext context = new JdbcMappingContext();
+
+ // DATAJDBC-188
+ @Test
+ public void simpleEntityDoesntReferenceOtherEntities() {
+
+ List paths = context.referencedEntities(SimpleEntity.class, null);
+
+ assertThat(paths).isEmpty();
+ }
+
+ // DATAJDBC-188
+ @Test
+ public void cascadingReferencesGetFound() {
+
+ List paths = context.referencedEntities(CascadingEntity.class, null);
+
+ assertThat(paths).extracting(PropertyPath::toDotPath) //
+ .containsExactly( //
+ "reference.reference", //
+ "reference" //
+ );
+ }
+
+ // DATAJDBC-188
+ @Test
+ public void setReferencesGetFound() {
+
+ List paths = context.referencedEntities(EntityWithSet.class, null);
+
+ assertThat(paths).extracting(PropertyPath::toDotPath) //
+ .containsExactly( //
+ "set.reference", //
+ "set" //
+ );
+ }
+
+ // DATAJDBC-188
+ @Test
+ public void mapReferencesGetFound() {
+
+ List paths = context.referencedEntities(EntityWithMap.class, null);
+
+ assertThat(paths).extracting(PropertyPath::toDotPath) //
+ .containsExactly( //
+ "map.reference", //
+ "map" //
+ );
+ }
+
+ private static class SimpleEntity {
+ String name;
+ }
+
+ private static class CascadingEntity {
+ MiddleEntity reference;
+ }
+
+ private static class MiddleEntity {
+ SimpleEntity reference;
+ }
+
+ private static class EntityWithMap {
+ Map map;
+ }
+
+ private static class EntityWithSet {
+ Set set;
+ }
+}