diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java index ac69a5b39..9707a6deb 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java @@ -26,7 +26,6 @@ import org.springframework.data.jdbc.core.convert.DataAccessStrategy; import org.springframework.data.mapping.IdentifierAccessor; import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.conversion.AggregateChange.Kind; import org.springframework.data.relational.core.conversion.Interpreter; import org.springframework.data.relational.core.conversion.RelationalConverter; import org.springframework.data.relational.core.conversion.RelationalEntityDeleteWriter; @@ -331,33 +330,30 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { triggerAfterDelete(entity, id, change); } - @SuppressWarnings({ "unchecked", "rawtypes" }) private AggregateChange createInsertChange(T instance) { - AggregateChange aggregateChange = new AggregateChange(Kind.SAVE, instance.getClass(), instance); + AggregateChange aggregateChange = AggregateChange.forSave(instance); jdbcEntityInsertWriter.write(instance, aggregateChange); return aggregateChange; } - @SuppressWarnings({ "unchecked", "rawtypes" }) private AggregateChange createUpdateChange(T instance) { - AggregateChange aggregateChange = new AggregateChange(Kind.SAVE, instance.getClass(), instance); + AggregateChange aggregateChange = AggregateChange.forSave(instance); jdbcEntityUpdateWriter.write(instance, aggregateChange); return aggregateChange; } - @SuppressWarnings({ "unchecked", "rawtypes" }) private AggregateChange createDeletingChange(Object id, @Nullable T entity, Class domainType) { - AggregateChange aggregateChange = new AggregateChange(Kind.DELETE, domainType, entity); + AggregateChange aggregateChange = AggregateChange.forDelete(domainType, entity); jdbcEntityDeleteWriter.write(id, aggregateChange); return aggregateChange; } private AggregateChange createDeletingChange(Class domainType) { - AggregateChange aggregateChange = new AggregateChange<>(Kind.DELETE, domainType, null); + AggregateChange aggregateChange = AggregateChange.forDelete(domainType, null); jdbcEntityDeleteWriter.write(null, aggregateChange); return aggregateChange; } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChange.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChange.java index 6ef32fd29..6319ba841 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChange.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChange.java @@ -25,6 +25,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.BiConsumer; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; @@ -34,6 +35,7 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentEnti import org.springframework.data.util.Pair; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * Represents the change happening to the aggregate (as used in the context of Domain Driven Design) as a whole. @@ -59,7 +61,53 @@ public class AggregateChange { this.entity = entity; } + /** + * Factory method to create an {@link AggregateChange} for saving entities. + * + * @param entity aggregate root to save. + * @param entity type. + * @return the {@link AggregateChange} for saving the root {@code entity}. + * @since 1.2 + */ + @SuppressWarnings("unchecked") + public static AggregateChange forSave(T entity) { + + Assert.notNull(entity, "Entity must not be null"); + return new AggregateChange<>(Kind.SAVE, (Class) ClassUtils.getUserClass(entity), entity); + } + + /** + * Factory method to create an {@link AggregateChange} for deleting entities. + * + * @param entity aggregate root to delete. + * @param entity type. + * @return the {@link AggregateChange} for deleting the root {@code entity}. + * @since 1.2 + */ + @SuppressWarnings("unchecked") + public static AggregateChange forDelete(T entity) { + + Assert.notNull(entity, "Entity must not be null"); + return forDelete((Class) ClassUtils.getUserClass(entity), entity); + } + + /** + * Factory method to create an {@link AggregateChange} for deleting entities. + * + * @param entityClass aggregate root type. + * @param entity aggregate root to delete. + * @param entity type. + * @return the {@link AggregateChange} for deleting the root {@code entity}. + * @since 1.2 + */ + public static AggregateChange forDelete(Class entityClass, @Nullable T entity) { + + Assert.notNull(entityClass, "Entity class must not be null"); + return new AggregateChange<>(Kind.DELETE, entityClass, entity); + } + public void setEntity(@Nullable T aggregateRoot) { + // TODO: Check instanceOf compatibility to ensure type contract. entity = aggregateRoot; } @@ -67,16 +115,15 @@ public class AggregateChange { actions.forEach(action -> action.executeWith(interpreter)); - T newRoot = setGeneratedIds(context, converter); + T newRoot = populateIdsIfNecessary(context, converter); if (newRoot != null) { entity = newRoot; } } - @SuppressWarnings("unchecked") @Nullable - private T setGeneratedIds(RelationalMappingContext context, RelationalConverter converter) { + private T populateIdsIfNecessary(RelationalMappingContext context, RelationalConverter converter) { T newRoot = null; @@ -84,32 +131,31 @@ public class AggregateChange { ArrayList> reverseActions = new ArrayList<>(actions); Collections.reverse(reverseActions); - CascadingValuesLookup cascadingValues = new CascadingValuesLookup(); + StagedValues cascadingValues = new StagedValues(); for (DbAction action : reverseActions) { - if (action instanceof DbAction.WithGeneratedId) { - - DbAction.WithGeneratedId withGeneratedId = (DbAction.WithGeneratedId) action; - Object generatedId = withGeneratedId.getGeneratedId(); + if (!(action instanceof DbAction.WithGeneratedId)) { + continue; + } - Object newEntity = setIdAndCascadingProperties(context, converter, withGeneratedId, generatedId, - cascadingValues); + DbAction.WithGeneratedId withGeneratedId = (DbAction.WithGeneratedId) action; + Object generatedId = withGeneratedId.getGeneratedId(); + Object newEntity = setIdAndCascadingProperties(context, converter, withGeneratedId, generatedId, cascadingValues); - // the id property was immutable so we have to propagate changes up the tree - if (newEntity != ((DbAction.WithGeneratedId) action).getEntity()) { + // the id property was immutable so we have to propagate changes up the tree + if (newEntity != ((DbAction.WithGeneratedId) action).getEntity()) { - if (action instanceof DbAction.Insert) { - DbAction.Insert insert = (DbAction.Insert) action; + if (action instanceof DbAction.Insert) { + DbAction.Insert insert = (DbAction.Insert) action; - Pair qualifier = insert.getQualifier(); + Pair qualifier = insert.getQualifier(); - cascadingValues.add(insert.dependingOn, insert.propertyPath, newEntity, - qualifier == null ? null : qualifier.getSecond()); + cascadingValues.stage(insert.dependingOn, insert.propertyPath, + qualifier == null ? null : qualifier.getSecond(), newEntity); - } else if (action instanceof DbAction.InsertRoot) { - newRoot = (T) newEntity; - } + } else if (action instanceof DbAction.InsertRoot) { + newRoot = entityType.cast(newEntity); } } } @@ -119,7 +165,7 @@ public class AggregateChange { @SuppressWarnings("unchecked") private Object setIdAndCascadingProperties(RelationalMappingContext context, RelationalConverter converter, - DbAction.WithGeneratedId action, @Nullable Object generatedId, CascadingValuesLookup cascadingValues) { + DbAction.WithGeneratedId action, @Nullable Object generatedId, StagedValues cascadingValues) { S originalEntity = action.getEntity(); @@ -132,19 +178,14 @@ public class AggregateChange { } // set values of changed immutables referenced by this entity - Map cascadingValue = cascadingValues.get(action); - for (Map.Entry pathValuePair : cascadingValue.entrySet()) { - propertyAccessor.setProperty(getRelativePath(action, pathValuePair), pathValuePair.getValue()); - } + cascadingValues.forEachPath(action, (persistentPropertyPath, o) -> propertyAccessor + .setProperty(getRelativePath(action, persistentPropertyPath), o)); return propertyAccessor.getBean(); } @SuppressWarnings("unchecked") - private PersistentPropertyPath getRelativePath(DbAction action, - Map.Entry pathValuePair) { - - PersistentPropertyPath pathToValue = pathValuePair.getKey(); + private PersistentPropertyPath getRelativePath(DbAction action, PersistentPropertyPath pathToValue) { if (action instanceof DbAction.Insert) { return pathToValue.getExtensionForBaseOf(((DbAction.Insert) action).propertyPath); @@ -178,12 +219,13 @@ public class AggregateChange { } /** - * Gathers and holds information about immutable properties in an aggregate that need updating. + * Accumulates information about staged immutable objects in an aggregate that require updating because their state + * changed because of {@link DbAction} execution. */ - private static class CascadingValuesLookup { + private static class StagedValues { - static final List aggregators = Arrays.asList(new SetAggregator(), new MapAggregator(), - new ListAggregator(), new SingleElementAggregator()); + static final List aggregators = Arrays.asList(SetAggregator.INSTANCE, MapAggregator.INSTANCE, + ListAggregator.INSTANCE, SingleElementAggregator.INSTANCE); Map> values = new HashMap<>(); @@ -194,27 +236,22 @@ public class AggregateChange { * @param action The action responsible for persisting the entity that needs the added value set. Must not be * {@literal null}. * @param path The path to the property in which to set the value. Must not be {@literal null}. - * @param value The value to be set. Must not be {@literal null}. * @param qualifier If {@code path} is a qualified multivalued properties this parameter contains the qualifier. May * be {@literal null}. + * @param value The value to be set. Must not be {@literal null}. */ @SuppressWarnings("unchecked") - public void add(DbAction action, PersistentPropertyPath path, Object value, @Nullable Object qualifier) { + void stage(DbAction action, PersistentPropertyPath path, @Nullable Object qualifier, Object value) { MultiValueAggregator aggregator = getAggregatorFor(path); - Map valuesForPath = this.values.get(action); - if (valuesForPath == null) { - valuesForPath = new HashMap<>(); - values.put(action, valuesForPath); - } + Map valuesForPath = this.values.computeIfAbsent(action, + dbAction -> new HashMap<>()); - T currentValue = (T) valuesForPath.get(path); - if (currentValue == null) { - currentValue = aggregator.createEmptyInstance(); - } + T currentValue = (T) valuesForPath.computeIfAbsent(path, + persistentPropertyPath -> aggregator.createEmptyInstance()); - Object newValue = aggregator.add(currentValue, value, qualifier); + Object newValue = aggregator.add(currentValue, qualifier, value); valuesForPath.put(path, newValue); } @@ -231,8 +268,17 @@ public class AggregateChange { throw new IllegalStateException(String.format("Can't handle path %s", path)); } - public Map get(DbAction action) { - return values.getOrDefault(action, Collections.emptyMap()); + /** + * Performs the given action for each entry in this the staging area that are provided by {@link DbAction} until all + * {@link PersistentPropertyPath} have been processed or the action throws an exception. The {@link BiConsumer + * action} is called with each applicable {@link PersistentPropertyPath} and {@code value} that is assignable to the + * property. + * + * @param dbAction + * @param action + */ + void forEachPath(DbAction dbAction, BiConsumer action) { + values.getOrDefault(dbAction, Collections.emptyMap()).forEach(action); } } @@ -249,11 +295,13 @@ public class AggregateChange { @Nullable T createEmptyInstance(); - T add(@Nullable T aggregate, Object value, @Nullable Object qualifier); + T add(@Nullable T aggregate, @Nullable Object qualifier, Object value); } - static private class SetAggregator implements MultiValueAggregator { + private enum SetAggregator implements MultiValueAggregator { + + INSTANCE; @Override public Class handledType() { @@ -267,7 +315,7 @@ public class AggregateChange { @SuppressWarnings("unchecked") @Override - public Set add(@Nullable Set set, Object value, @Nullable Object qualifier) { + public Set add(@Nullable Set set, @Nullable Object qualifier, Object value) { Assert.notNull(set, "Set must not be null"); @@ -276,7 +324,9 @@ public class AggregateChange { } } - static private class ListAggregator implements MultiValueAggregator { + private enum ListAggregator implements MultiValueAggregator { + + INSTANCE; @Override public boolean handles(PersistentProperty property) { @@ -290,7 +340,7 @@ public class AggregateChange { @SuppressWarnings("unchecked") @Override - public List add(@Nullable List list, Object value, @Nullable Object qualifier) { + public List add(@Nullable List list, @Nullable Object qualifier, Object value) { Assert.notNull(list, "List must not be null."); @@ -305,7 +355,9 @@ public class AggregateChange { } } - static private class MapAggregator implements MultiValueAggregator { + private enum MapAggregator implements MultiValueAggregator { + + INSTANCE; @Override public Class handledType() { @@ -319,7 +371,7 @@ public class AggregateChange { @SuppressWarnings("unchecked") @Override - public Map add(@Nullable Map map, Object value, @Nullable Object qualifier) { + public Map add(@Nullable Map map, @Nullable Object qualifier, Object value) { Assert.notNull(map, "Map must not be null."); @@ -328,7 +380,9 @@ public class AggregateChange { } } - static private class SingleElementAggregator implements MultiValueAggregator { + private enum SingleElementAggregator implements MultiValueAggregator { + + INSTANCE; @Override @Nullable @@ -337,7 +391,7 @@ public class AggregateChange { } @Override - public Object add(@Nullable Object __null, Object value, @Nullable Object qualifier) { + public Object add(@Nullable Object __null, @Nullable Object qualifier, Object value) { return value; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java index 7d092f742..24948e91a 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java @@ -262,6 +262,9 @@ public interface DbAction { */ Map, Object> getQualifiers(); + // TODO: Encapsulate propertyPath and qualifier in object: PropertyPathWithListIndex, + // PropertyPathWithMapIndex, PropertyPathInSet, PropertyPathWithoutQualifier + // Probably we need better names. @Nullable default Pair, Object> getQualifier() { Map, Object> qualifiers = getQualifiers(); @@ -272,14 +275,14 @@ public interface DbAction { throw new IllegalStateException("Can't handle more then on qualifier"); } - Map.Entry, Object> entry = qualifiers.entrySet().iterator().next(); + Map.Entry, Object> entry = qualifiers.entrySet().iterator() + .next(); if (entry.getValue() == null) { return null; } return Pair.of(entry.getKey(), entry.getValue()); }; - @Override default Class getEntityType() { return WithEntity.super.getEntityType(); diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeIdGenerationImmutableUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeIdGenerationImmutableUnitTests.java index bf2bcb636..491a24878 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeIdGenerationImmutableUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeIdGenerationImmutableUnitTests.java @@ -18,6 +18,7 @@ package org.springframework.data.relational.core.conversion; import static java.util.Arrays.*; import static java.util.Collections.*; import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.SoftAssertions.*; import lombok.AllArgsConstructor; import lombok.Value; @@ -30,8 +31,8 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.assertj.core.api.SoftAssertions; import org.junit.Test; + import org.springframework.data.annotation.Id; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.PersistentPropertyPaths; @@ -41,7 +42,8 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProp import org.springframework.lang.Nullable; /** - * Unit tests for the {@link AggregateChange} testing the setting of generated ids in aggregates consisting of immutable entities. + * Unit tests for the {@link AggregateChange} testing the setting of generated ids in aggregates consisting of immutable + * entities. * * @author Jens Schauder * @author Myeonghyeon-Lee @@ -59,14 +61,12 @@ public class AggregateChangeIdGenerationImmutableUnitTests { RelationalMappingContext context = new RelationalMappingContext(); RelationalConverter converter = new BasicRelationalConverter(context); - DbAction.WithEntity rootInsert = new DbAction.InsertRoot<>(entity); @Test // DATAJDBC-291 public void singleRoot() { - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.executeWith(new IdSettingInterpreter(), context, converter); @@ -81,8 +81,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = entity.withSingle(content); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(createInsert("single", content, null)); @@ -90,7 +89,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = aggregateChange.getEntity(); - SoftAssertions.assertSoftly(softly -> { + assertSoftly(softly -> { softly.assertThat(entity.rootId).isEqualTo(1); softly.assertThat(entity.single.id).isEqualTo(2); @@ -102,8 +101,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = entity.withContentList(asList(content, content2)); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(createInsert("contentList", content, 0)); aggregateChange.addAction(createInsert("contentList", content2, 1)); @@ -112,7 +110,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = aggregateChange.getEntity(); - SoftAssertions.assertSoftly(softly -> { + assertSoftly(softly -> { softly.assertThat(entity.rootId).isEqualTo(1); softly.assertThat(entity.contentList).extracting(c -> c.id).containsExactly(2, 3); @@ -124,8 +122,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = entity.withContentMap(createContentMap("a", content, "b", content2)); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(createInsert("contentMap", content, "a")); aggregateChange.addAction(createInsert("contentMap", content2, "b")); @@ -147,8 +144,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { DbAction.Insert parentInsert = createInsert("single", content, null); DbAction.Insert insert = createDeepInsert("single", tag1, null, parentInsert); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert); aggregateChange.addAction(insert); @@ -172,8 +168,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { DbAction.Insert insert1 = createDeepInsert("tagList", tag1, 0, parentInsert); DbAction.Insert insert2 = createDeepInsert("tagList", tag2, 1, parentInsert); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert); aggregateChange.addAction(insert1); @@ -183,7 +178,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = aggregateChange.getEntity(); - SoftAssertions.assertSoftly(softly -> { + assertSoftly(softly -> { softly.assertThat(entity.rootId).isEqualTo(1); softly.assertThat(entity.single.id).isEqualTo(2); @@ -201,8 +196,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { DbAction.Insert insert1 = createDeepInsert("tagSet", tag1, null, parentInsert); DbAction.Insert insert2 = createDeepInsert("tagSet", tag2, null, parentInsert); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert); aggregateChange.addAction(insert1); @@ -212,7 +206,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = aggregateChange.getEntity(); - SoftAssertions.assertSoftly(softly -> { + assertSoftly(softly -> { softly.assertThat(entity.rootId).isEqualTo(1); softly.assertThat(entity.contentSet) // @@ -237,8 +231,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { DbAction.Insert insert1 = createDeepInsert("single", tag1, null, parentInsert1); DbAction.Insert insert2 = createDeepInsert("single", tag2, null, parentInsert2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert1); aggregateChange.addAction(parentInsert2); @@ -249,7 +242,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = aggregateChange.getEntity(); - SoftAssertions.assertSoftly(softly -> { + assertSoftly(softly -> { softly.assertThat(entity.rootId).isEqualTo(1); softly.assertThat(entity.contentList) // @@ -271,8 +264,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { DbAction.Insert insert2 = createDeepInsert("tagList", tag2, 0, parentInsert2); DbAction.Insert insert3 = createDeepInsert("tagList", tag3, 1, parentInsert2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert1); aggregateChange.addAction(parentInsert2); @@ -284,7 +276,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = aggregateChange.getEntity(); - SoftAssertions.assertSoftly(softly -> { + assertSoftly(softly -> { softly.assertThat(entity.rootId).isEqualTo(1); softly.assertThat(entity.contentList) // @@ -309,8 +301,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { DbAction.Insert insert2 = createDeepInsert("tagMap", tag2, "222", parentInsert2); DbAction.Insert insert3 = createDeepInsert("tagMap", tag3, "333", parentInsert2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert1); aggregateChange.addAction(parentInsert2); @@ -322,7 +313,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = aggregateChange.getEntity(); - SoftAssertions.assertSoftly(softly -> { + assertSoftly(softly -> { softly.assertThat(entity.rootId).isEqualTo(1); softly.assertThat(entity.contentMap.entrySet()) // @@ -351,8 +342,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { DbAction.Insert insert1 = createDeepInsert("single", tag1, null, parentInsert1); DbAction.Insert insert2 = createDeepInsert("single", tag2, null, parentInsert2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert1); aggregateChange.addAction(parentInsert2); @@ -363,7 +353,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { entity = aggregateChange.getEntity(); - SoftAssertions.assertSoftly(softly -> { + assertSoftly(softly -> { softly.assertThat(entity.rootId).isEqualTo(1); softly.assertThat(entity.contentNoIdList) // @@ -380,8 +370,7 @@ public class AggregateChangeIdGenerationImmutableUnitTests { DbAction.Insert parentInsert = createInsert("embedded.single", tag1, null); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert); @@ -441,11 +430,10 @@ public class AggregateChangeIdGenerationImmutableUnitTests { 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() - .orElseThrow(() -> new IllegalArgumentException("No matching path found for " + pathValue)); + return new WritingContext(context, entity, AggregateChange.forSave(root)).insert().stream() + .filter(a -> a instanceof DbAction.Insert).map(DbAction.Insert.class::cast) + .filter(a -> a.getEntity() == pathValue).map(DbAction.Insert::getPropertyPath).findFirst() + .orElseThrow(() -> new IllegalArgumentException("No matching path found for " + pathValue)); } @Value diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeIdGenerationUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeIdGenerationUnitTests.java index c9fd5b343..b3c2377c1 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeIdGenerationUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/AggregateChangeIdGenerationUnitTests.java @@ -37,7 +37,7 @@ import org.springframework.lang.Nullable; * Unit tests for the {@link AggregateChange}. * * @author Jens Schauder - * Myeonghyeon-Lee + * @author Myeonghyeon-Lee */ public class AggregateChangeIdGenerationUnitTests { @@ -50,14 +50,12 @@ public class AggregateChangeIdGenerationUnitTests { RelationalMappingContext context = new RelationalMappingContext(); RelationalConverter converter = new BasicRelationalConverter(context); - DbAction.WithEntity rootInsert = new DbAction.InsertRoot<>(entity); @Test // DATAJDBC-291 public void singleRoot() { - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.executeWith(new IdSettingInterpreter(), context, converter); @@ -70,8 +68,7 @@ public class AggregateChangeIdGenerationUnitTests { entity.single = content; - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(createInsert("single", content, null)); @@ -90,8 +87,7 @@ public class AggregateChangeIdGenerationUnitTests { entity.contentList.add(content); entity.contentList.add(content2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(createInsert("contentList", content, 0)); aggregateChange.addAction(createInsert("contentList", content2, 1)); @@ -111,8 +107,7 @@ public class AggregateChangeIdGenerationUnitTests { entity.contentMap.put("a", content); entity.contentMap.put("b", content2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(createInsert("contentMap", content, "a")); aggregateChange.addAction(createInsert("contentMap", content2, "b")); @@ -132,8 +127,7 @@ public class AggregateChangeIdGenerationUnitTests { DbAction.Insert parentInsert = createInsert("single", content, null); DbAction.Insert insert = createDeepInsert("single", tag1, null, parentInsert); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert); aggregateChange.addAction(insert); @@ -156,8 +150,7 @@ public class AggregateChangeIdGenerationUnitTests { DbAction.Insert insert1 = createDeepInsert("tagList", tag1, 0, parentInsert); DbAction.Insert insert2 = createDeepInsert("tagList", tag2, 1, parentInsert); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert); aggregateChange.addAction(insert1); @@ -184,8 +177,7 @@ public class AggregateChangeIdGenerationUnitTests { DbAction.Insert insert1 = createDeepInsert("tagSet", tag1, null, parentInsert); DbAction.Insert insert2 = createDeepInsert("tagSet", tag2, null, parentInsert); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert); aggregateChange.addAction(insert1); @@ -219,8 +211,7 @@ public class AggregateChangeIdGenerationUnitTests { DbAction.Insert insert1 = createDeepInsert("single", tag1, null, parentInsert1); DbAction.Insert insert2 = createDeepInsert("single", tag2, null, parentInsert2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert1); aggregateChange.addAction(parentInsert2); @@ -253,8 +244,7 @@ public class AggregateChangeIdGenerationUnitTests { DbAction.Insert insert2 = createDeepInsert("tagList", tag2, 0, parentInsert2); DbAction.Insert insert3 = createDeepInsert("tagList", tag3, 1, parentInsert2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert1); aggregateChange.addAction(parentInsert2); @@ -292,8 +282,7 @@ public class AggregateChangeIdGenerationUnitTests { DbAction.Insert insert2 = createDeepInsert("tagMap", tag2, "222", parentInsert2); DbAction.Insert insert3 = createDeepInsert("tagMap", tag3, "333", parentInsert2); - AggregateChange aggregateChange = new AggregateChange<>(AggregateChange.Kind.SAVE, DummyEntity.class, - entity); + AggregateChange aggregateChange = AggregateChange.forSave(entity); aggregateChange.addAction(rootInsert); aggregateChange.addAction(parentInsert1); aggregateChange.addAction(parentInsert2); @@ -348,11 +337,10 @@ public class AggregateChangeIdGenerationUnitTests { 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() - .orElseThrow(() -> new IllegalArgumentException("No matching path found")); + return new WritingContext(context, entity, AggregateChange.forSave(root)).insert().stream() + .filter(a -> a instanceof DbAction.Insert).map(DbAction.Insert.class::cast) + .filter(a -> a.getEntity() == pathValue).map(DbAction.Insert::getPropertyPath).findFirst() + .orElseThrow(() -> new IllegalArgumentException("No matching path found")); } private static class DummyEntity {