diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java index f36056e52..24376bf89 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java @@ -56,7 +56,6 @@ class AggregateChangeExecutor { } return root; - } private void execute(DbAction action, JdbcAggregateChangeExecutionContext executionContext) { @@ -85,5 +84,4 @@ class AggregateChangeExecutor { throw new DbActionExecutionException(action, e); } } - } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java index 785c730b9..59e4b145a 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java @@ -34,7 +34,6 @@ import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.relational.core.conversion.AggregateChangeExecutionContext; import org.springframework.data.relational.core.conversion.DbAction; import org.springframework.data.relational.core.conversion.DbActionExecutionResult; import org.springframework.data.relational.core.conversion.RelationalEntityVersionUtils; @@ -49,7 +48,7 @@ import org.springframework.util.Assert; /** * @author Jens Schauder */ -class JdbcAggregateChangeExecutionContext implements AggregateChangeExecutionContext { +class JdbcAggregateChangeExecutionContext { private static final String UPDATE_FAILED = "Failed to update entity [%s]. Id [%s] not found in database."; private static final String UPDATE_FAILED_OPTIMISTIC_LOCKING = "Failed to update entity [%s]. The entity was updated since it was rea or it isn't in the database at all."; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutorContextUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutorContextUnitTests.java index d970812ca..2c68629f4 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutorContextUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutorContextUnitTests.java @@ -38,6 +38,11 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProp import org.springframework.data.relational.domain.Identifier; import org.springframework.lang.Nullable; +/** + * Unit tests for {@link JdbcAggregateChangeExecutionContext}. + * + * @author Jens Schauder + */ public class JdbcAggregateChangeExecutorContextUnitTests { RelationalMappingContext context = new RelationalMappingContext(); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateUnitTests.java index 078b5264c..3eeebd594 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateUnitTests.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.annotation.Id; import org.springframework.data.domain.PageRequest; 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 9f22d7665..d45a59a1e 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 @@ -1,18 +1,32 @@ +/* + * Copyright 2017-2020 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 + * + * https://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.relational.core.conversion; import java.util.function.Consumer; import org.springframework.lang.Nullable; +/** + * Represents the change happening to the aggregate (as used in the context of Domain Driven Design) as a whole. + * + * @author Jens Schauder + * @author Mark Paluch + */ public interface AggregateChange { - /** - * Applies the given consumer to each {@link DbAction} in this {@code AggregateChange}. - * - * @param consumer must not be {@literal null}. - */ - void forEachAction(Consumer> consumer); - /** * Returns the {@link Kind} of {@code AggregateChange} this is. * @@ -35,10 +49,18 @@ public interface AggregateChange { @Nullable T getEntity(); + /** + * Applies the given consumer to each {@link DbAction} in this {@code AggregateChange}. + * + * @param consumer must not be {@literal null}. + */ + void forEachAction(Consumer> consumer); + /** * The kind of action to be performed on an aggregate. */ enum Kind { + /** * A {@code SAVE} of an aggregate typically involves an {@code insert} or {@code update} on the aggregate root plus * {@code insert}s, {@code update}s, and {@code delete}s on the other elements of an aggregate. diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChangeExecutionContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChangeExecutionContext.java deleted file mode 100644 index 660c33fad..000000000 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/AggregateChangeExecutionContext.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.springframework.data.relational.core.conversion; - -public interface AggregateChangeExecutionContext {} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java new file mode 100644 index 000000000..e8262bff0 --- /dev/null +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java @@ -0,0 +1,118 @@ +/* + * Copyright 2017-2020 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 + * + * https://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.relational.core.conversion; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Represents the change happening to the aggregate (as used in the context of Domain Driven Design) as a whole. + * + * @author Jens Schauder + * @author Mark Paluch + * @since 2.0 + */ +class DefaultAggregateChange implements MutableAggregateChange { + + private final Kind kind; + + /** Type of the aggregate root to be changed */ + private final Class entityType; + + private final List> actions = new ArrayList<>(); + + /** Aggregate root, to which the change applies, if available */ + private @Nullable T entity; + + public DefaultAggregateChange(Kind kind, Class entityType, @Nullable T entity) { + + this.kind = kind; + this.entityType = entityType; + this.entity = entity; + } + + /** + * Adds an action to this {@code AggregateChange}. + * + * @param action must not be {@literal null}. + */ + @Override + public void addAction(DbAction action) { + + Assert.notNull(action, "Action must not be null."); + + actions.add(action); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.relational.core.conversion.AggregateChange#getKind() + */ + @Override + public Kind getKind() { + return this.kind; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.relational.core.conversion.AggregateChange#getEntityType() + */ + @Override + public Class getEntityType() { + return this.entityType; + } + + /** + * Set the root object of the {@code AggregateChange}. + * + * @param aggregateRoot may be {@literal null} if the change refers to a list of aggregates or references it by id. + */ + @Override + public void setEntity(@Nullable T aggregateRoot) { + + if (aggregateRoot != null) { + Assert.isInstanceOf(this.entityType, aggregateRoot, + String.format("AggregateRoot must be of type %s", entityType.getName())); + } + + this.entity = aggregateRoot; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.relational.core.conversion.AggregateChange#getEntity() + */ + @Override + public T getEntity() { + return this.entity; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.relational.core.conversion.AggregateChange#forEachAction(java.util.function.Consumer) + */ + @Override + public void forEachAction(Consumer> consumer) { + + Assert.notNull(consumer, "Consumer must not be null."); + + actions.forEach(consumer); + } +} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java index a7dc54595..5cc89bbf6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2020 the original author or authors. + * Copyright 2020 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. @@ -15,10 +15,6 @@ */ package org.springframework.data.relational.core.conversion; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -28,24 +24,9 @@ import org.springframework.util.ClassUtils; * * @author Jens Schauder * @author Mark Paluch + * @since 2.0 */ -public class MutableAggregateChange implements AggregateChange { - - private final Kind kind; - - /** Type of the aggregate root to be changed */ - private final Class entityType; - - private final List> actions = new ArrayList<>(); - /** Aggregate root, to which the change applies, if available */ - @Nullable private T entity; - - public MutableAggregateChange(Kind kind, Class entityType, @Nullable T entity) { - - this.kind = kind; - this.entityType = entityType; - this.entity = entity; - } +public interface MutableAggregateChange extends AggregateChange { /** * Factory method to create an {@link MutableAggregateChange} for saving entities. @@ -56,10 +37,11 @@ public class MutableAggregateChange implements AggregateChange { * @since 1.2 */ @SuppressWarnings("unchecked") - public static MutableAggregateChange forSave(T entity) { + static MutableAggregateChange forSave(T entity) { Assert.notNull(entity, "Entity must not be null"); - return new MutableAggregateChange<>(Kind.SAVE, (Class) ClassUtils.getUserClass(entity), entity); + + return new DefaultAggregateChange<>(Kind.SAVE, (Class) ClassUtils.getUserClass(entity), entity); } /** @@ -71,9 +53,10 @@ public class MutableAggregateChange implements AggregateChange { * @since 1.2 */ @SuppressWarnings("unchecked") - public static MutableAggregateChange forDelete(T entity) { + static MutableAggregateChange forDelete(T entity) { Assert.notNull(entity, "Entity must not be null"); + return forDelete((Class) ClassUtils.getUserClass(entity), entity); } @@ -86,81 +69,24 @@ public class MutableAggregateChange implements AggregateChange { * @return the {@link MutableAggregateChange} for deleting the root {@code entity}. * @since 1.2 */ - public static MutableAggregateChange forDelete(Class entityClass, @Nullable T entity) { + static MutableAggregateChange forDelete(Class entityClass, @Nullable T entity) { Assert.notNull(entityClass, "Entity class must not be null"); - return new MutableAggregateChange<>(Kind.DELETE, entityClass, entity); + + return new DefaultAggregateChange<>(Kind.DELETE, entityClass, entity); } /** * Adds an action to this {@code AggregateChange}. - * + * * @param action must not be {@literal null}. */ - public void addAction(DbAction action) { - - Assert.notNull(action, "Action must not be null."); - - actions.add(action); - } - - /** - * Applies the given consumer to each {@link DbAction} in this {@code AggregateChange}. - * - * @param consumer must not be {@literal null}. - */ - @Override - public void forEachAction(Consumer> consumer) { - - Assert.notNull(consumer, "Consumer must not be null."); - - actions.forEach(consumer); - } - - /** - * Returns the {@link Kind} of {@code AggregateChange} this is. - * - * @return guaranteed to be not {@literal null}. - */ - @Override - public Kind getKind() { - return this.kind; - } - - /** - * The type of the root of this {@code AggregateChange}. - * - * @return Guaranteed to be not {@literal null}. - */ - @Override - public Class getEntityType() { - return this.entityType; - } + void addAction(DbAction action); /** * Set the root object of the {@code AggregateChange}. * * @param aggregateRoot may be {@literal null} if the change refers to a list of aggregates or references it by id. */ - public void setEntity(@Nullable T aggregateRoot) { - - if (aggregateRoot != null) { - Assert.isInstanceOf(entityType, aggregateRoot, - String.format("AggregateRoot must be of type %s", entityType.getName())); - } - - entity = aggregateRoot; - } - - /** - * The entity to which this {@link MutableAggregateChange} relates. - * - * @return may be {@literal null}. - */ - @Override - @Nullable - public T getEntity() { - return this.entity; - } - + void setEntity(@Nullable T aggregateRoot); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java index 0ca38e239..64af552a4 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java @@ -81,7 +81,7 @@ public class RelationalEntityDeleteWriter implements EntityWriter List> deleteRoot(Object id, MutableAggregateChange aggregateChange) { + private List> deleteRoot(Object id, AggregateChange aggregateChange) { List> actions = new ArrayList<>(deleteReferencedEntities(id, aggregateChange)); actions.add(new DbAction.DeleteRoot<>(id, aggregateChange.getEntityType(), getVersion(aggregateChange))); @@ -90,12 +90,12 @@ public class RelationalEntityDeleteWriter implements EntityWriter> deleteReferencedEntities(Object id, MutableAggregateChange aggregateChange) { + private List> deleteReferencedEntities(Object id, AggregateChange aggregateChange) { List> actions = new ArrayList<>(); @@ -108,7 +108,7 @@ public class RelationalEntityDeleteWriter implements EntityWriter aggregateChange) { + private Number getVersion(AggregateChange aggregateChange) { RelationalPersistentEntity persistentEntity = context .getRequiredPersistentEntity(aggregateChange.getEntityType()); 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 b8e4e36fc..11c311c90 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 @@ -46,8 +46,8 @@ class WritingContext { private final Object entity; private final Class entityType; private final PersistentPropertyPaths paths; - private final Map previousActions = new HashMap<>(); - private Map, List> nodesCache = new HashMap<>(); + private final Map> previousActions = new HashMap<>(); + private final Map, List> nodesCache = new HashMap<>(); WritingContext(RelationalMappingContext context, Object root, MutableAggregateChange aggregateChange) { @@ -180,7 +180,7 @@ class WritingContext { @Nullable private DbAction.WithEntity getAction(@Nullable PathNode parent) { - DbAction action = previousActions.get(parent); + DbAction action = previousActions.get(parent); if (action != null) { @@ -274,7 +274,7 @@ class WritingContext { ((Map) value).forEach((k, v) -> nodes.add(new PathNode(path, parentNode, Pair.of(k, v)))); } else { - List listValue = (List) value; + List listValue = (List) value; for (int k = 0; k < listValue.size(); k++) { nodes.add(new PathNode(path, parentNode, Pair.of(k, listValue.get(k)))); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.java index 810349727..5559a0489 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.java @@ -16,7 +16,6 @@ package org.springframework.data.relational.core.mapping.event; import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.conversion.MutableAggregateChange; import org.springframework.lang.Nullable; /** @@ -33,8 +32,8 @@ public class AfterDeleteEvent extends RelationalDeleteEvent { /** * @param id of the entity. Must not be {@literal null}. * @param instance the deleted entity if it is available. May be {@literal null}. - * @param change the {@link MutableAggregateChange} encoding the actions that were performed on the database as part - * of the delete operation. Must not be {@literal null}. + * @param change the {@link AggregateChange} encoding the actions that were performed on the database as part of the + * delete operation. Must not be {@literal null}. */ public AfterDeleteEvent(Identifier id, @Nullable E instance, AggregateChange change) { super(id, instance, change); diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveEvent.java index e50a66b68..f761b1b29 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterSaveEvent.java @@ -16,7 +16,6 @@ package org.springframework.data.relational.core.mapping.event; import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.conversion.MutableAggregateChange; /** * Gets published after a new instance or a changed instance was saved in the database. @@ -29,8 +28,7 @@ public class AfterSaveEvent extends RelationalSaveEvent { /** * @param instance the saved entity. Must not be {@literal null}. - * @param change the {@link MutableAggregateChange} encoding the actions performed on the database as part of the - * delete. + * @param change the {@link AggregateChange} encoding the actions performed on the database as part of the delete. * Must not be {@literal null}. */ public AfterSaveEvent(E instance, AggregateChange change) { diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.java index cca27d086..7964a599c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteCallback.java @@ -16,7 +16,6 @@ package org.springframework.data.relational.core.mapping.event; import org.springframework.data.mapping.callback.EntityCallback; -import org.springframework.data.relational.core.conversion.AggregateChange; import org.springframework.data.relational.core.conversion.MutableAggregateChange; /** @@ -25,6 +24,7 @@ import org.springframework.data.relational.core.conversion.MutableAggregateChang * or without any parameter don't invoke this callback. * * @author Jens Schauder + * @author Mark Paluch * @since 1.1 */ @FunctionalInterface @@ -37,8 +37,8 @@ public interface BeforeDeleteCallback extends EntityCallback { * account for deleting. Only transient fields of the entity should be changed in this callback. * * @param aggregate the aggregate. - * @param aggregateChange the associated {@link MutableAggregateChange}. + * @param aggregateChange the associated {@link DefaultAggregateChange}. * @return the aggregate to be deleted. */ - T onBeforeDelete(T aggregate, AggregateChange aggregateChange); + T onBeforeDelete(T aggregate, MutableAggregateChange aggregateChange); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.java index 7c3709d4f..1087a97ee 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.java @@ -16,12 +16,10 @@ package org.springframework.data.relational.core.mapping.event; import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.conversion.MutableAggregateChange; import org.springframework.lang.Nullable; /** - * Gets published when an entity is about to get deleted. The contained {@link MutableAggregateChange} is mutable and - * may be changed in order to change the actions that get performed on the database as part of the delete operation. + * Gets published when an entity is about to get deleted. * * @author Jens Schauder */ @@ -32,7 +30,7 @@ public class BeforeDeleteEvent extends RelationalDeleteEvent { /** * @param id the id of the entity. Must not be {@literal null}. * @param entity the entity about to get deleted. May be {@literal null}. - * @param change the {@link MutableAggregateChange} encoding the planned actions to be performed on the database. + * @param change the {@link AggregateChange} containing the planned actions to be performed on the database. */ public BeforeDeleteEvent(Identifier id, @Nullable E entity, AggregateChange change) { super(id, entity, change); diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.java index bffbd2f81..7f7e27f2e 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveCallback.java @@ -16,7 +16,6 @@ package org.springframework.data.relational.core.mapping.event; import org.springframework.data.mapping.callback.EntityCallback; -import org.springframework.data.relational.core.conversion.AggregateChange; import org.springframework.data.relational.core.conversion.MutableAggregateChange; /** @@ -34,12 +33,11 @@ public interface BeforeSaveCallback extends EntityCallback { * Entity callback method invoked before an aggregate root is saved. Can return either the same or a modified instance * of the aggregate and can modify {@link MutableAggregateChange} contents. This method is called after converting the * {@code aggregate} to {@link MutableAggregateChange}. Changes to the aggregate are not taken into account for - * saving. Only transient fields of the entity should be changed in this callback. To change persistent the entity - * before being converted, use the {@link BeforeConvertCallback}. + * saving. Use the {@link BeforeConvertCallback} to change the persistent the entity before being converted. * * @param aggregate the aggregate. * @param aggregateChange the associated {@link MutableAggregateChange}. * @return the aggregate object to be persisted. */ - T onBeforeSave(T aggregate, AggregateChange aggregateChange); + T onBeforeSave(T aggregate, MutableAggregateChange aggregateChange); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.java index 066ac8d8a..b2a3ec8b2 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeSaveEvent.java @@ -16,11 +16,9 @@ package org.springframework.data.relational.core.mapping.event; import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.conversion.MutableAggregateChange; /** - * Gets published before an entity gets saved to the database. The contained {@link MutableAggregateChange} is mutable - * and may be changed in order to change the actions that get performed on the database as part of the save operation. + * Gets published before an entity gets saved to the database. * * @author Jens Schauder */ @@ -30,7 +28,7 @@ public class BeforeSaveEvent extends RelationalSaveEvent { /** * @param instance the entity about to get saved. Must not be {@literal null}. - * @param change the {@link MutableAggregateChange} that is going to get applied to the database. Must not be + * @param change the {@link AggregateChange} that is going to get applied to the database. Must not be * {@literal null}. */ public BeforeSaveEvent(E instance, AggregateChange change) { diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java index 5c60bf48d..9d10632be 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java @@ -19,6 +19,7 @@ import org.springframework.data.relational.core.conversion.AggregateChange; /** * {@link RelationalEvent} that represents a change to an aggregate and therefore has an {@link AggregateChange} + * * @author Jens Schauder */ public interface WithAggregateChange extends RelationalEvent { diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriterUnitTests.java index 9e3578845..09e819161 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriterUnitTests.java @@ -47,8 +47,7 @@ public class RelationalEntityDeleteWriterUnitTests { SomeEntity entity = new SomeEntity(23L); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.DELETE, - SomeEntity.class, entity); + MutableAggregateChange aggregateChange = MutableAggregateChange.forDelete(SomeEntity.class, entity); converter.write(entity.id, aggregateChange); @@ -64,8 +63,7 @@ public class RelationalEntityDeleteWriterUnitTests { @Test // DATAJDBC-188 public void deleteAllDeletesAllEntitiesAndReferencedEntities() { - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.DELETE, - SomeEntity.class, null); + MutableAggregateChange aggregateChange = MutableAggregateChange.forDelete(SomeEntity.class, null); converter.write(null, aggregateChange); diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriterUnitTests.java index 0be97d980..9c4b9d9fd 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityInsertWriterUnitTests.java @@ -45,7 +45,7 @@ public class RelationalEntityInsertWriterUnitTests { SingleReferenceEntity entity = new SingleReferenceEntity(null); MutableAggregateChange aggregateChange = // - new MutableAggregateChange(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); + MutableAggregateChange.forSave(entity); converter.write(entity, aggregateChange); @@ -63,7 +63,7 @@ public class RelationalEntityInsertWriterUnitTests { SingleReferenceEntity entity = new SingleReferenceEntity(SOME_ENTITY_ID); MutableAggregateChange aggregateChange = // - new MutableAggregateChange(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); + MutableAggregateChange.forSave(entity); converter.write(entity, aggregateChange); diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriterUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriterUnitTests.java index 5b7d5df7d..4a1cac2fc 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriterUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityUpdateWriterUnitTests.java @@ -45,8 +45,7 @@ public class RelationalEntityUpdateWriterUnitTests { SingleReferenceEntity entity = new SingleReferenceEntity(SOME_ENTITY_ID); - MutableAggregateChange aggregateChange = // - new MutableAggregateChange(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); + MutableAggregateChange aggregateChange = MutableAggregateChange.forSave(entity); converter.write(entity, aggregateChange); 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 13879d4ac..0ca00f6b5 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 @@ -80,7 +80,7 @@ public class RelationalEntityWriterUnitTests { SingleReferenceEntity entity = new SingleReferenceEntity(null); MutableAggregateChange aggregateChange = // - new MutableAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); + new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); converter.write(entity, aggregateChange); @@ -102,7 +102,7 @@ public class RelationalEntityWriterUnitTests { entity.other = new Element(2L); MutableAggregateChange aggregateChange = // - new MutableAggregateChange<>(AggregateChange.Kind.SAVE, EmbeddedReferenceEntity.class, entity); + new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EmbeddedReferenceEntity.class, entity); converter.write(entity, aggregateChange); @@ -124,7 +124,7 @@ public class RelationalEntityWriterUnitTests { entity.other = new Element(null); MutableAggregateChange aggregateChange = // - new MutableAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); + new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); converter.write(entity, aggregateChange); @@ -146,7 +146,7 @@ public class RelationalEntityWriterUnitTests { SingleReferenceEntity entity = new SingleReferenceEntity(SOME_ENTITY_ID); MutableAggregateChange aggregateChange = // - new MutableAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); + new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); converter.write(entity, aggregateChange); @@ -168,7 +168,7 @@ public class RelationalEntityWriterUnitTests { SingleReferenceEntity entity = new SingleReferenceEntity(SOME_ENTITY_ID); entity.other = new Element(null); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>( + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>( AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity); converter.write(entity, aggregateChange); @@ -190,7 +190,7 @@ public class RelationalEntityWriterUnitTests { public void newEntityWithEmptySetResultsInSingleInsert() { SetContainer entity = new SetContainer(null); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SetContainer.class, entity); converter.write(entity, aggregateChange); @@ -212,7 +212,7 @@ public class RelationalEntityWriterUnitTests { entity.elements.add(new Element(null)); entity.elements.add(new Element(null)); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SetContainer.class, entity); converter.write(entity, aggregateChange); @@ -243,7 +243,7 @@ public class RelationalEntityWriterUnitTests { new Element(null)) // ); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>( + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>( AggregateChange.Kind.SAVE, CascadingReferenceEntity.class, entity); converter.write(entity, aggregateChange); @@ -281,7 +281,7 @@ public class RelationalEntityWriterUnitTests { new Element(null)) // ); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>( + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>( AggregateChange.Kind.SAVE, CascadingReferenceEntity.class, entity); converter.write(entity, aggregateChange); @@ -310,7 +310,7 @@ public class RelationalEntityWriterUnitTests { public void newEntityWithEmptyMapResultsInSingleInsert() { MapContainer entity = new MapContainer(null); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, MapContainer.class, entity); converter.write(entity, aggregateChange); @@ -329,7 +329,7 @@ public class RelationalEntityWriterUnitTests { entity.elements.put("one", new Element(null)); entity.elements.put("two", new Element(null)); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, MapContainer.class, entity); converter.write(entity, aggregateChange); @@ -368,7 +368,7 @@ public class RelationalEntityWriterUnitTests { entity.elements.put("a", new Element(null)); entity.elements.put("b", new Element(null)); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, MapContainer.class, entity); converter.write(entity, aggregateChange); @@ -397,7 +397,7 @@ public class RelationalEntityWriterUnitTests { public void newEntityWithEmptyListResultsInSingleInsert() { ListContainer entity = new ListContainer(null); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, ListContainer.class, entity); converter.write(entity, aggregateChange); @@ -416,7 +416,7 @@ public class RelationalEntityWriterUnitTests { entity.elements.add(new Element(null)); entity.elements.add(new Element(null)); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, ListContainer.class, entity); converter.write(entity, aggregateChange); @@ -443,7 +443,7 @@ public class RelationalEntityWriterUnitTests { MapContainer entity = new MapContainer(SOME_ENTITY_ID); entity.elements.put("one", new Element(null)); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, MapContainer.class, entity); converter.write(entity, aggregateChange); @@ -466,7 +466,7 @@ public class RelationalEntityWriterUnitTests { ListContainer entity = new ListContainer(SOME_ENTITY_ID); entity.elements.add(new Element(null)); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, ListContainer.class, entity); converter.write(entity, aggregateChange); @@ -490,7 +490,7 @@ public class RelationalEntityWriterUnitTests { listMapContainer.maps.add(new MapContainer(SOME_ENTITY_ID)); listMapContainer.maps.get(0).elements.put("one", new Element(null)); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>(AggregateChange.Kind.SAVE, + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, ListMapContainer.class, listMapContainer); converter.write(listMapContainer, aggregateChange); @@ -517,7 +517,7 @@ public class RelationalEntityWriterUnitTests { listMapContainer.maps.add(new NoIdMapContainer()); listMapContainer.maps.get(0).elements.put("one", new NoIdElement()); - MutableAggregateChange aggregateChange = new MutableAggregateChange<>( + MutableAggregateChange aggregateChange = new DefaultAggregateChange<>( AggregateChange.Kind.SAVE, NoIdListMapContainer.class, listMapContainer); converter.write(listMapContainer, aggregateChange); @@ -544,7 +544,7 @@ public class RelationalEntityWriterUnitTests { // the embedded is null !!! MutableAggregateChange aggregateChange = // - new MutableAggregateChange<>(AggregateChange.Kind.SAVE, EmbeddedReferenceChainEntity.class, entity); + new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EmbeddedReferenceChainEntity.class, entity); converter.write(entity, aggregateChange); @@ -567,7 +567,7 @@ public class RelationalEntityWriterUnitTests { // the embedded is null !!! MutableAggregateChange aggregateChange = // - new MutableAggregateChange<>(AggregateChange.Kind.SAVE, RootWithEmbeddedReferenceChainEntity.class, root); + new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, RootWithEmbeddedReferenceChainEntity.class, root); converter.write(root, aggregateChange);