From 22f9eded6036e95ab651e9cf5e8d9369d3e9dbbc Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 13 Mar 2020 08:58:24 +0100 Subject: [PATCH] DATAJDBC-454 - Redesigned events. Ids are only contained if it can not be guaranteed that an entity is contained which applies to the delete events. As a side effect Identifier got simplified into a single simple class. Original pull request: #199. --- .../data/jdbc/core/JdbcAggregateTemplate.java | 41 ++-- .../support/JdbcRepositoryQuery.java | 9 +- ...ryManipulateDbActionsIntegrationTests.java | 232 ------------------ .../SimpleJdbcRepositoryEventsUnitTests.java | 16 +- .../JdbcRepositoryFactoryBeanUnitTests.java | 10 +- .../core/mapping/event/AfterDeleteEvent.java | 20 +- .../core/mapping/event/AfterLoadEvent.java | 15 +- .../core/mapping/event/AfterSaveEvent.java | 13 +- .../mapping/event/BeforeConvertEvent.java | 18 +- .../core/mapping/event/BeforeDeleteEvent.java | 15 +- .../core/mapping/event/BeforeSaveEvent.java | 15 +- .../core/mapping/event/Identifier.java | 65 +++-- .../mapping/event/RelationalDeleteEvent.java | 71 ++++++ .../core/mapping/event/RelationalEvent.java | 20 +- .../event/RelationalEventWithEntity.java | 26 +- .../mapping/event/RelationalEventWithId.java | 52 ---- .../event/RelationalEventWithIdAndEntity.java | 39 --- .../mapping/event/RelationalSaveEvent.java | 41 ++++ .../mapping/event/SimpleRelationalEvent.java | 76 ------ .../mapping/event/SpecifiedIdentifier.java | 44 ---- .../{Unset.java => WithAggregateChange.java} | 22 +- .../core/mapping/event/WithEntity.java | 7 +- .../relational/core/mapping/event/WithId.java | 9 +- .../mapping/event/IdentifierUnitTests.java | 57 ----- 24 files changed, 261 insertions(+), 672 deletions(-) delete mode 100644 spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryManipulateDbActionsIntegrationTests.java create mode 100644 spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalDeleteEvent.java delete mode 100644 spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithId.java delete mode 100644 spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithIdAndEntity.java create mode 100644 spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalSaveEvent.java delete mode 100644 spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/SimpleRelationalEvent.java delete mode 100644 spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/SpecifiedIdentifier.java rename spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/{Unset.java => WithAggregateChange.java} (64%) delete mode 100644 spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/event/IdentifierUnitTests.java 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 a7d75ae23..8eae5681f 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 @@ -17,7 +17,6 @@ package org.springframework.data.jdbc.core; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -40,7 +39,6 @@ import org.springframework.data.relational.core.conversion.RelationalEntityUpdat import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.event.*; -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -212,7 +210,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { T entity = accessStrategy.findById(id, domainType); if (entity != null) { - return triggerAfterLoad(id, entity); + return triggerAfterLoad(entity); } return entity; } @@ -337,8 +335,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { AggregateChange change = changeCreator.apply(aggregateRoot); - aggregateRoot = triggerBeforeSave(aggregateRoot, - persistentEntity.getIdentifierAccessor(aggregateRoot).getIdentifier(), change); + aggregateRoot = triggerBeforeSave(aggregateRoot, change); change.setEntity(aggregateRoot); @@ -348,7 +345,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { Assert.notNull(identifier, "After saving the identifier must not be null!"); - return triggerAfterSave(change.getEntity(), identifier, change); + return triggerAfterSave(change.getEntity(), change); } private void deleteTree(Object id, @Nullable T entity, Class domainType) { @@ -396,19 +393,15 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { List result = new ArrayList<>(); for (T e : all) { - - RelationalPersistentEntity entity = context.getRequiredPersistentEntity(e.getClass()); - IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(e); - - result.add(triggerAfterLoad(identifierAccessor.getRequiredIdentifier(), e)); + result.add(triggerAfterLoad(e)); } return result; } - private T triggerAfterLoad(Object id, T entity) { + private T triggerAfterLoad(T entity) { - publisher.publishEvent(new AfterLoadEvent(Identifier.of(id), entity)); + publisher.publishEvent(new AfterLoadEvent(entity)); return entityCallbacks.callback(AfterLoadCallback.class, entity); } @@ -417,33 +410,27 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { return entityCallbacks.callback(BeforeConvertCallback.class, aggregateRoot); } - private T triggerBeforeSave(T aggregateRoot, @Nullable Object id, AggregateChange change) { + private T triggerBeforeSave(T aggregateRoot, AggregateChange change) { publisher.publishEvent(new BeforeSaveEvent( // - Identifier.ofNullable(id), // + // aggregateRoot, // - change // - )); + // + change)); return entityCallbacks.callback(BeforeSaveCallback.class, aggregateRoot, change); } - private T triggerAfterSave(T aggregateRoot, Object id, AggregateChange change) { + private T triggerAfterSave(T aggregateRoot, AggregateChange change) { - Specified identifier = Identifier.of(id); - - publisher.publishEvent(new AfterSaveEvent( // - identifier, // - aggregateRoot, // - change // - )); + publisher.publishEvent(new AfterSaveEvent(aggregateRoot, change)); return entityCallbacks.callback(AfterSaveCallback.class, aggregateRoot); } private void triggerAfterDelete(@Nullable T aggregateRoot, Object id, AggregateChange change) { - publisher.publishEvent(new AfterDeleteEvent(Identifier.of(id), Optional.ofNullable(aggregateRoot), change)); + publisher.publishEvent(new AfterDeleteEvent(Identifier.of(id), aggregateRoot, change)); if (aggregateRoot != null) { entityCallbacks.callback(AfterDeleteCallback.class, aggregateRoot); @@ -453,7 +440,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { @Nullable private T triggerBeforeDelete(@Nullable T aggregateRoot, Object id, AggregateChange change) { - publisher.publishEvent(new BeforeDeleteEvent(Identifier.of(id), Optional.ofNullable(aggregateRoot), change)); + publisher.publishEvent(new BeforeDeleteEvent(Identifier.of(id), aggregateRoot, change)); if (aggregateRoot != null) { return entityCallbacks.callback(BeforeDeleteCallback.class, aggregateRoot, change); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryQuery.java index 3de4b35b8..a50000075 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryQuery.java @@ -31,7 +31,6 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; import org.springframework.data.relational.core.mapping.event.AfterLoadCallback; import org.springframework.data.relational.core.mapping.event.AfterLoadEvent; -import org.springframework.data.relational.core.mapping.event.Identifier; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.jdbc.core.ResultSetExtractor; @@ -213,10 +212,8 @@ class JdbcRepositoryQuery implements RepositoryQuery { MapSqlParameterSource parameters = new MapSqlParameterSource(); - queryMethod.getParameters().getBindableParameters().forEach(p -> { - - convertAndAddParameter(parameters, p, objects[p.getIndex()]); - }); + queryMethod.getParameters().getBindableParameters() + .forEach(p -> convertAndAddParameter(parameters, p, objects[p.getIndex()])); return parameters; } @@ -291,7 +288,7 @@ class JdbcRepositoryQuery implements RepositoryQuery { Object identifier = e.getIdentifierAccessor(entity).getIdentifier(); if (identifier != null) { - publisher.publishEvent(new AfterLoadEvent(Identifier.of(identifier), entity)); + publisher.publishEvent(new AfterLoadEvent(entity)); } callbacks.callback(AfterLoadCallback.class, entity); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryManipulateDbActionsIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryManipulateDbActionsIntegrationTests.java deleted file mode 100644 index 1548ee439..000000000 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryManipulateDbActionsIntegrationTests.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 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.jdbc.repository; - -import static java.util.Arrays.*; -import static org.assertj.core.api.Assertions.*; - -import junit.framework.AssertionFailedError; -import lombok.Data; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; - -import java.util.List; -import java.util.Random; - -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; -import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; -import org.springframework.data.jdbc.testing.TestConfiguration; -import org.springframework.data.relational.core.conversion.DbAction; -import org.springframework.data.relational.core.mapping.event.BeforeDeleteEvent; -import org.springframework.data.relational.core.mapping.event.BeforeSaveEvent; -import org.springframework.data.repository.CrudRepository; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.rules.SpringClassRule; -import org.springframework.test.context.junit4.rules.SpringMethodRule; - -/** - * Tests that the event infrastructure of Spring Data JDBC is sufficient to manipulate the {@link DbAction}s to be - * executed against the database. - * - * @author Jens Schauder - * @author Greg Turnquist - */ -@ContextConfiguration -public class JdbcRepositoryManipulateDbActionsIntegrationTests { - - @ClassRule public static final SpringClassRule classRule = new SpringClassRule(); - @Rule public SpringMethodRule methodRule = new SpringMethodRule(); - - @Autowired DummyEntityRepository repository; - @Autowired LogRepository logRepository; - - @Test // DATAJDBC-120 - public void softDelete() { - - // given a persistent entity - DummyEntity entity = new DummyEntity(null, "Hello"); - repository.save(entity); - assertThat(entity.id).isNotNull(); - - // when I delete the entity - repository.delete(entity); - - // it is still in the repository, but marked as deleted - assertThat(repository.findById(entity.id)) // - .contains(new DummyEntity( // - entity.id, // - entity.name, // - true) // - ); - - } - - @Test // DATAJDBC-120 - public void softDeleteMany() { - - // given persistent entities - DummyEntity one = new DummyEntity(null, "One"); - DummyEntity two = new DummyEntity(null, "Two"); - repository.saveAll(asList(one, two)); - - assertThat(one.id).isNotNull(); - - // when I delete the entities - repository.deleteAll(asList(one, two)); - - // they are still in the repository, but marked as deleted - assertThat(repository.findById(one.id)) // - .contains(new DummyEntity( // - one.id, // - one.name, // - true) // - ); - - assertThat(repository.findById(two.id)) // - .contains(new DummyEntity( // - two.id, // - two.name, // - true) // - ); - } - - @Test // DATAJDBC-120 - public void loggingOnSave() { - - // given a new entity - DummyEntity one = new DummyEntity(null, "one"); - - repository.save(one); - assertThat(one.id).isNotNull(); - - // they are still in the repository, but marked as deleted - assertThat(logRepository.findById(Config.lastLogId)) // - .isNotEmpty() // - .map(Log::getText) // - .contains("one saved"); - } - - @Test // DATAJDBC-120 - public void loggingOnSaveMany() { - - // given a new entity - DummyEntity one = new DummyEntity(null, "one"); - DummyEntity two = new DummyEntity(null, "two"); - - repository.saveAll(asList(one, two)); - assertThat(one.id).isNotNull(); - - // they are still in the repository, but marked as deleted - assertThat(logRepository.findById(Config.lastLogId)) // - .isNotEmpty() // - .map(Log::getText) // - .contains("two saved"); - } - - @Data - private static class DummyEntity { - - @Id Long id; - String name; - boolean deleted; - - DummyEntity(Long id, String name) { - - this.id = id; - this.name = name; - this.deleted = false; - } - - @PersistenceConstructor - DummyEntity(Long id, String name, boolean deleted) { - - this.id = id; - this.name = name; - this.deleted = deleted; - } - } - - private interface DummyEntityRepository extends CrudRepository {} - - @Getter - @Setter - @RequiredArgsConstructor - private static class Log { - - @Id Long id; - DummyEntity entity; - String text; - } - - private interface LogRepository extends CrudRepository {} - - @Configuration - @Import(TestConfiguration.class) - @EnableJdbcRepositories(considerNestedRepositories = true) - static class Config { - - static long lastLogId; - - @Bean - Class testClass() { - return JdbcRepositoryManipulateDbActionsIntegrationTests.class; - } - - @Bean - ApplicationListener softDeleteListener() { - - return event -> { - - DummyEntity entity = (DummyEntity) event.getOptionalEntity().orElseThrow(AssertionFailedError::new); - entity.deleted = true; - - List> actions = event.getChange().getActions(); - actions.clear(); - actions.add(new DbAction.UpdateRoot<>(entity)); - }; - } - - @Bean - ApplicationListener logOnSaveListener() { - - // this would actually be easier to implement with an AfterSaveEvent listener, but we want to test AggregateChange - // manipulation. - return event -> { - - DummyEntity entity = (DummyEntity) event.getOptionalEntity().orElseThrow(AssertionFailedError::new); - lastLogId = new Random().nextLong(); - Log log = new Log(); - log.setId(lastLogId); - log.entity = entity; - log.text = entity.name + " saved"; - - List> actions = event.getChange().getActions(); - actions.add(new DbAction.InsertRoot<>(log)); - }; - } - } -} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java index 9126b559b..22f9cad49 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java @@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import junit.framework.AssertionFailedError; import lombok.RequiredArgsConstructor; import lombok.Value; import lombok.With; @@ -57,11 +56,13 @@ import org.springframework.data.relational.core.mapping.event.BeforeDeleteEvent; import org.springframework.data.relational.core.mapping.event.BeforeSaveEvent; import org.springframework.data.relational.core.mapping.event.Identifier; import org.springframework.data.relational.core.mapping.event.RelationalEvent; +import org.springframework.data.relational.core.mapping.event.WithId; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.KeyHolder; +import org.springframework.lang.Nullable; /** * Unit tests for application events via {@link SimpleJdbcRepository}. @@ -143,14 +144,23 @@ public class SimpleJdbcRepositoryEventsUnitTests { assertThat(publisher.events).extracting( // RelationalEvent::getClass, // - e -> e.getOptionalEntity().orElseGet(AssertionFailedError::new), // - RelationalEvent::getId // + this::getEntity, // + this::getId // ).containsExactly( // Tuple.tuple(BeforeDeleteEvent.class, entity, Identifier.of(23L)), // Tuple.tuple(AfterDeleteEvent.class, entity, Identifier.of(23L)) // ); } + private Identifier getId(RelationalEvent e) { + return ((WithId) e).getId(); + } + + @Nullable + private Object getEntity(RelationalEvent e) { + return e.getEntity(); + } + @Test // DATAJDBC-99 @SuppressWarnings("rawtypes") public void publishesEventsOnDeleteById() { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBeanUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBeanUnitTests.java index 2824dd3ae..c816d9ec8 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBeanUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactoryBeanUnitTests.java @@ -61,8 +61,7 @@ public class JdbcRepositoryFactoryBeanUnitTests { @Mock DataAccessStrategy dataAccessStrategy; @Mock ApplicationEventPublisher publisher; @Mock(answer = Answers.RETURNS_DEEP_STUBS) ListableBeanFactory beanFactory; - @Mock - Dialect dialect; + @Mock Dialect dialect; RelationalMappingContext mappingContext; @@ -78,10 +77,11 @@ public class JdbcRepositoryFactoryBeanUnitTests { ObjectProvider provider = mock(ObjectProvider.class); when(beanFactory.getBeanProvider(DataAccessStrategy.class)).thenReturn(provider); - when(provider.getIfAvailable(any())).then((Answer) invocation -> ((Supplier) invocation.getArgument(0)).get()); + when(provider.getIfAvailable(any())) + .then((Answer) invocation -> ((Supplier) invocation.getArgument(0)).get()); } - @Test + @Test // DATAJDBC-151 public void setsUpBasicInstanceCorrectly() { factoryBean.setDataAccessStrategy(dataAccessStrategy); @@ -95,7 +95,7 @@ public class JdbcRepositoryFactoryBeanUnitTests { assertThat(factoryBean.getObject()).isNotNull(); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = IllegalArgumentException.class) // DATAJDBC-151 public void requiresListableBeanFactory() { factoryBean.setBeanFactory(mock(BeanFactory.class)); 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 6f80d745b..b87e752fa 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 @@ -15,28 +15,28 @@ */ package org.springframework.data.relational.core.mapping.event; -import java.util.Optional; - import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; +import org.springframework.lang.Nullable; /** - * Gets published after deletion of an entity. It will have a {@link Specified} identifier. If the entity is empty or + * Gets published after deletion of an entity. It will have a {@link Identifier} identifier. If the entity is {@literal null} or * not depends on the delete method used. * * @author Jens Schauder */ -public class AfterDeleteEvent extends RelationalEventWithId { +public class AfterDeleteEvent extends RelationalDeleteEvent { - private static final long serialVersionUID = 3594807189931141582L; + private static final long serialVersionUID = 2615043444207870206L; /** - * @param id of the entity. - * @param instance the deleted entity if it is available. + * @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 AggregateChange} encoding the actions that were performed on the database as part of the - * delete operation. + * delete operation. Must not be {@literal null}. */ - public AfterDeleteEvent(Specified id, Optional instance, AggregateChange change) { + public AfterDeleteEvent(Identifier id, @Nullable Object instance, AggregateChange change) { super(id, instance, change); } + + } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java index 587a80fde..a39bd2574 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java @@ -15,23 +15,20 @@ */ package org.springframework.data.relational.core.mapping.event; -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; - /** * Gets published after instantiation and setting of all the properties of an entity. This allows to do some - * postprocessing of entities. + * postprocessing of entities if the entities are mutable. For immutable entities use {@link AfterLoadCallback}. * * @author Jens Schauder */ -public class AfterLoadEvent extends RelationalEventWithIdAndEntity { +public class AfterLoadEvent extends RelationalEventWithEntity { - private static final long serialVersionUID = -4185777271143436728L; + private static final long serialVersionUID = 7343072117054666699L; /** - * @param id of the entity - * @param entity the newly instantiated entity. + * @param entity the newly instantiated entity. Must not be {@literal null}. */ - public AfterLoadEvent(Specified id, Object entity) { - super(id, entity, null); + public AfterLoadEvent(Object entity) { + super(entity); } } 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 8782b885f..36dda0e4d 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,23 +16,22 @@ package org.springframework.data.relational.core.mapping.event; import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; /** * Gets published after a new instance or a changed instance was saved in the database. * * @author Jens Schauder */ -public class AfterSaveEvent extends RelationalEventWithIdAndEntity { +public class AfterSaveEvent extends RelationalSaveEvent { - private static final long serialVersionUID = 8982085767296982848L; + private static final long serialVersionUID = 1681164473866370396L; /** - * @param id identifier of the saved entity. - * @param instance the saved entity. + * @param instance the saved entity. Must not be {@literal null}. * @param change the {@link AggregateChange} encoding the actions performed on the database as part of the delete. + * Must not be {@literal null}. */ - public AfterSaveEvent(Specified id, Object instance, AggregateChange change) { - super(id, instance, change); + public AfterSaveEvent(Object instance, AggregateChange change) { + super(instance, change); } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.java index bc731ae1c..d99a00fc1 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/BeforeConvertEvent.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.mapping.event.Identifier.Specified; /** * Gets published before an aggregate gets converted into a database change. @@ -24,16 +23,19 @@ import org.springframework.data.relational.core.mapping.event.Identifier.Specifi * @since 1.1 * @author Jens Schauder */ -public class BeforeConvertEvent extends RelationalEventWithIdAndEntity { +public class BeforeConvertEvent extends RelationalSaveEvent { - private static final long serialVersionUID = 3980149746683849019L; + private static final long serialVersionUID = -5716795164911939224L; /** - * @param id identifier of the saved entity. - * @param instance the saved entity. - * @param change the {@link AggregateChange} encoding the actions performed on the database as part of the delete. + * @param instance the saved entity. Must not be {@literal null}. + * @param change the {@link AggregateChange} encoding the actions to be performed on the database as change. Since + * this event is fired before the conversion the change is actually empty, but contains information if the + * aggregate is considered new in {@link AggregateChange#getKind()}. Must not be {@literal null}. */ - public BeforeConvertEvent(Specified id, Object instance, AggregateChange change) { - super(id, instance, change); + public BeforeConvertEvent(Object instance, AggregateChange change) { + + super(instance, change); + } } 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 7a704469c..f9509093b 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 @@ -15,10 +15,8 @@ */ package org.springframework.data.relational.core.mapping.event; -import java.util.Optional; - import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; +import org.springframework.lang.Nullable; /** * Gets published when an entity is about to get deleted. The contained {@link AggregateChange} is mutable and may be @@ -26,16 +24,17 @@ import org.springframework.data.relational.core.mapping.event.Identifier.Specifi * * @author Jens Schauder */ -public class BeforeDeleteEvent extends RelationalEventWithId { +public class BeforeDeleteEvent extends RelationalDeleteEvent { - private static final long serialVersionUID = -5483432053368496651L; + private static final long serialVersionUID = -137285843224094551L; /** - * @param id the id of the entity - * @param entity the entity about to get deleted. Might be empty. + * @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 AggregateChange} encoding the planned actions to be performed on the database. */ - public BeforeDeleteEvent(Specified id, Optional entity, AggregateChange change) { + public BeforeDeleteEvent(Identifier id, @Nullable Object entity, AggregateChange change) { super(id, entity, change); } + } 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 9b9babc9d..7c9293d57 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 @@ -23,16 +23,17 @@ import org.springframework.data.relational.core.conversion.AggregateChange; * * @author Jens Schauder */ -public class BeforeSaveEvent extends RelationalEventWithEntity { +public class BeforeSaveEvent extends RelationalSaveEvent{ - private static final long serialVersionUID = -6996874391990315443L; + private static final long serialVersionUID = -4935804431519314116L; /** - * @param id of the entity to be saved. - * @param instance the entity about to get saved. - * @param change the {@link AggregateChange} that is going to get applied to the database. + * @param instance the entity about to get saved. Must not be {@literal null}. + * @param change the {@link AggregateChange} that is going to get applied to the database. Must not be {@literal null}. + * */ - public BeforeSaveEvent(Identifier id, Object instance, AggregateChange change) { - super(id, instance, change); + public BeforeSaveEvent(Object instance, AggregateChange change) { + super(instance, change); + } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Identifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Identifier.java index 4b7cce6c1..868f58ce4 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Identifier.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Identifier.java @@ -15,62 +15,59 @@ */ package org.springframework.data.relational.core.mapping.event; -import java.util.Optional; +import java.util.Objects; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Wrapper for an identifier of an entity. Might either be a {@link Specified} or {@link Unset#UNSET} + * Wrapper for an identifier of an entity. * * @author Jens Schauder */ -public interface Identifier { +public final class Identifier { - /** - * Creates a new {@link Specified} identifier for the given, non-null value. - * - * @param identifier must not be {@literal null}. - * @return will never be {@literal null}. - */ - static Specified of(Object identifier) { + private final Object value; + + private Identifier(Object value) { - Assert.notNull(identifier, "Identifier must not be null!"); + Assert.notNull(value, "Identifier must not be null!"); - return SpecifiedIdentifier.of(identifier); + this.value = value; } /** - * Produces an {@link Identifier} of appropriate type depending the argument being {@code null} or not. + * Creates a new {@link Identifier} identifier for the given, non-null value. * - * @param identifier May be {@code null}. - * @return an {@link Identifier}. + * @param identifier must not be {@literal null}. + * @return will never be {@literal null}. */ - static Identifier ofNullable(@Nullable Object identifier) { - return identifier == null ? Unset.UNSET : of(identifier); + public static Identifier of(Object identifier) { + + return new Identifier(identifier); } /** * Returns the identifier value. * - * @return will never be {@code null}. + * @return will never be {@literal null}. */ - Optional getOptionalValue(); + public Object getValue() { + return value; + } - /** - * A specified identifier that exposes a definitely present identifier value. - * - * @author Oliver Gierke - */ - interface Specified extends Identifier { + @Override + public boolean equals(Object o) { + + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Identifier that = (Identifier) o; + return value.equals(that.value); + } - /** - * Returns the identifier value. - * - * @return will never be {@literal null}. - */ - default Object getValue() { - return getOptionalValue().orElseThrow(() -> new IllegalStateException("Should not happen!")); - } + @Override + public int hashCode() { + return Objects.hash(value); } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalDeleteEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalDeleteEvent.java new file mode 100644 index 000000000..e8167f47e --- /dev/null +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalDeleteEvent.java @@ -0,0 +1,71 @@ +/* + * 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.mapping.event; + +import org.springframework.context.ApplicationEvent; +import org.springframework.data.relational.core.conversion.AggregateChange; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Super class for events produced during deleting an aggregate. Such events have an {@link Identifier} and an + * {@link AggregateChange} and may also have an entity if the entity was provided to the method performing the delete. + * + * @author Jens Schauder + */ +abstract public class RelationalDeleteEvent extends ApplicationEvent implements WithId, WithAggregateChange { + + private static final long serialVersionUID = -8071323168471611098L; + + private final Identifier id; + @Nullable private final Object entity; + private final AggregateChange change; + + /** + * @param id the identifier of the aggregate that gets deleted. Must not be {@literal null}. + * @param entity is the aggregate root that gets deleted. Might be {@literal null}. + * @param change the {@link AggregateChange} for the deletion containing more detailed information about the deletion + * process. + */ + RelationalDeleteEvent(Identifier id, @Nullable Object entity, AggregateChange change) { + + super(id); + + Assert.notNull(id, "Id must not be null."); + Assert.notNull(change, "Change must not be null."); + + this.id = id; + this.entity = entity; + this.change = change; + } + + @Override + public Identifier getId() { + return id; + } + + @Override + @Nullable + public Object getEntity() { + return entity; + } + + @Override + public AggregateChange getAggregateChange() { + return change; + } + +} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEvent.java index f830044c4..e7caf89d7 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEvent.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEvent.java @@ -15,28 +15,20 @@ */ package org.springframework.data.relational.core.mapping.event; +import org.springframework.lang.Nullable; + import java.util.Optional; /** - * an event signalling JDBC processing. It offers access to an {@link Identifier} of the aggregate root affected by the - * event. + * an event signalling JDBC processing. * * @author Oliver Gierke */ public interface RelationalEvent { /** - * The identifier of the aggregate root, triggering this event. - * - * @return the source of the event as an {@link Identifier}. Guaranteed to be not {@code null}. + * @return the entity to which this event refers. Might be {@literal null}. */ - Identifier getId(); - - /** - * Returns the aggregate root the event was triggered for. - * - * @return will never be {@code null}. - */ - Optional getOptionalEntity(); - + @Nullable + Object getEntity(); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithEntity.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithEntity.java index 28b0eb255..7c3bef28b 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithEntity.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithEntity.java @@ -15,20 +15,30 @@ */ package org.springframework.data.relational.core.mapping.event; -import java.util.Optional; - -import org.springframework.data.relational.core.conversion.AggregateChange; +import org.springframework.context.ApplicationEvent; /** - * A {@link SimpleRelationalEvent} which is guaranteed to have an entity. - * + * An event that is guaranteed to have an entity. + * * @author Jens Schauder */ -public class RelationalEventWithEntity extends SimpleRelationalEvent implements WithEntity { +public class RelationalEventWithEntity extends ApplicationEvent implements WithEntity { private static final long serialVersionUID = 4891455396602090638L; + private final Object entity; + + RelationalEventWithEntity(Object entity) { + + super(entity); + + this.entity = entity; + } - RelationalEventWithEntity(Identifier id, Object entity, AggregateChange change) { - super(id, Optional.of(entity), change); + /** + * @return the entity to which this event refers. Guaranteed to be not {@literal null}. + */ + @Override + public Object getEntity() { + return entity; } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithId.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithId.java deleted file mode 100644 index 86423d991..000000000 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithId.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.mapping.event; - -import java.util.Optional; - -import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; -import org.springframework.lang.Nullable; - -/** - * A {@link SimpleRelationalEvent} guaranteed to have an identifier. - * - * @author Jens Schauder - */ -public class RelationalEventWithId extends SimpleRelationalEvent implements WithId { - - private static final long serialVersionUID = -8071323168471611098L; - - private final Specified id; - - public RelationalEventWithId(Specified id, Optional entity, @Nullable AggregateChange change) { - - super(id, entity, change); - - this.id = id; - } - - /** - * Events with an identifier will always return a {@link Specified} one. - * - * @deprecated since 1.1, obtain the id from the entity instead. - */ - @Override - @Deprecated - public Specified getId() { - return id; - } -} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithIdAndEntity.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithIdAndEntity.java deleted file mode 100644 index e8b06d76b..000000000 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalEventWithIdAndEntity.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.mapping.event; - -import lombok.Getter; - -import java.util.Optional; - -import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; -import org.springframework.lang.Nullable; - -/** - * A {@link SimpleRelationalEvent} which is guaranteed to have an identifier and an entity. - * - * @author Jens Schauder - */ -@Getter -public class RelationalEventWithIdAndEntity extends RelationalEventWithId implements WithEntity { - - private static final long serialVersionUID = -3194462549552515519L; - - public RelationalEventWithIdAndEntity(Specified id, Object entity, @Nullable AggregateChange change) { - super(id, Optional.of(entity), change); - } -} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalSaveEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalSaveEvent.java new file mode 100644 index 000000000..17f611bc3 --- /dev/null +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/RelationalSaveEvent.java @@ -0,0 +1,41 @@ +package org.springframework.data.relational.core.mapping.event;/* + * 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. + * 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. + */ + +import org.springframework.data.relational.core.conversion.AggregateChange; +import org.springframework.util.Assert; + +/** + * Events triggered during saving of an aggregate. + * Events of this type always have an {@link AggregateChange} and an entity. + */ +public abstract class RelationalSaveEvent extends RelationalEventWithEntity implements WithAggregateChange{ + + private final AggregateChange change; + + RelationalSaveEvent(Object entity, AggregateChange change) { + + super(entity); + + Assert.notNull(change, "Change must not be null"); + + this.change = change; + } + + @Override + public AggregateChange getAggregateChange() { + return change; + } +} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/SimpleRelationalEvent.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/SimpleRelationalEvent.java deleted file mode 100644 index 64011c7c0..000000000 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/SimpleRelationalEvent.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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.mapping.event; - -import java.util.Optional; - -import org.springframework.context.ApplicationEvent; -import org.springframework.data.relational.core.conversion.AggregateChange; -import org.springframework.lang.Nullable; - -/** - * The common superclass for all events published by JDBC repositories. {@link #getSource} contains the - * {@link Identifier} of the entity triggering the event. - * - * @author Jens Schauder - * @author Oliver Gierke - */ -class SimpleRelationalEvent extends ApplicationEvent implements RelationalEvent { - - private static final long serialVersionUID = -1798807778668751659L; - - private final Object entity; - private final AggregateChange change; - - SimpleRelationalEvent(Identifier id, Optional entity, @Nullable AggregateChange change) { - - super(id); - - this.entity = entity.orElse(null); - this.change = change; - } - - /** - * @deprecated since 1.1, obtain the id from the entity instead. - */ - @Override - @Deprecated - public Identifier getId() { - return (Identifier) getSource(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.jdbc.core.mapping.event.JdbcEvent#getOptionalEntity() - */ - @Override - public Optional getOptionalEntity() { - return Optional.ofNullable(entity); - } - - /** - * Returns the an {@link AggregateChange} instance representing the SQL statements performed by the action that - * triggered this event. - * - * @return Guaranteed to be not {@literal null}. - * @deprecated There is currently no replacement for this. If something like this is required please create an issue - * outlining your use case. - */ - @Deprecated - public AggregateChange getChange() { - return change; - } -} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/SpecifiedIdentifier.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/SpecifiedIdentifier.java deleted file mode 100644 index 9f2beb398..000000000 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/SpecifiedIdentifier.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.mapping.event; - -import lombok.NonNull; -import lombok.Value; - -import java.util.Optional; - -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; - -/** - * Simple value object for {@link Specified}. - * - * @author Jens Schauder - * @author Oliver Gierke - */ -@Value(staticConstructor = "of") -class SpecifiedIdentifier implements Specified { - - @NonNull Object value; - - /* - * (non-Javadoc) - * @see org.springframework.data.jdbc.core.mapping.event.Identifier#getOptionalValue() - */ - @Override - public Optional getOptionalValue() { - return Optional.of(value); - } -} diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Unset.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java similarity index 64% rename from spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Unset.java rename to spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java index 7e39c7710..23fc87795 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/Unset.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithAggregateChange.java @@ -15,24 +15,16 @@ */ package org.springframework.data.relational.core.mapping.event; -import java.util.Optional; +import org.springframework.data.relational.core.conversion.AggregateChange; /** - * An unset identifier. Always returns {@link Optional#empty()} as value. - * - * @author Jens Schaude - * @author Oliver Gierke + * {@link RelationalEvent} that represents a change to an aggregate and therefore has an {@link AggregateChange} + * @author Jens Schauder */ -enum Unset implements Identifier { - - UNSET; +public interface WithAggregateChange extends RelationalEvent { - /* - * (non-Javadoc) - * @see org.springframework.data.jdbc.core.mapping.event.Identifier#getOptionalValue() + /** + * @return Guaranteed to be not {@literal null}. */ - @Override - public Optional getOptionalValue() { - return Optional.empty(); - } + AggregateChange getAggregateChange(); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithEntity.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithEntity.java index 78173cde2..c84cb8a8f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithEntity.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithEntity.java @@ -16,8 +16,7 @@ package org.springframework.data.relational.core.mapping.event; /** - * Interface for {@link SimpleRelationalEvent}s which are guaranteed to have an entity. Allows direct access to that - * entity, without going through an {@link java.util.Optional} + * Interface for events which are guaranteed to have an entity. * * @author Jens Schauder */ @@ -26,7 +25,5 @@ public interface WithEntity extends RelationalEvent { /** * @return will never be {@literal null}. */ - default Object getEntity() { - return getOptionalEntity().orElseThrow(() -> new IllegalStateException("Entity must not be NULL")); - } + Object getEntity(); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithId.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithId.java index 3ef279d30..e0c5713e8 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithId.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/WithId.java @@ -15,18 +15,15 @@ */ package org.springframework.data.relational.core.mapping.event; -import org.springframework.data.relational.core.mapping.event.Identifier.Specified; - /** - * Interface for {@link SimpleRelationalEvent}s which are guaranteed to have a {@link Specified} identifier. Offers - * direct access to the {@link Specified} identifier. + * Interface for {@link RelationalEvent}s which have an {@link Identifier} but might not have an entity. * * @author Jens Schauder */ public interface WithId extends RelationalEvent { /** - * Events with an identifier will always return a {@link Specified} one. + * Events with an identifier will always return a {@link Identifier} one. */ - Specified getId(); + Identifier getId(); } diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/event/IdentifierUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/event/IdentifierUnitTests.java deleted file mode 100644 index cfcb61267..000000000 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/event/IdentifierUnitTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2018-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.mapping.event; - -import static org.assertj.core.api.Assertions.*; - -import java.util.Optional; - -import org.junit.Test; - -/** - * Unit tests for {@link Identifier} - * - * @author Jens Schauder - */ -public class IdentifierUnitTests { - - @SuppressWarnings("unchecked") - @Test - public void specifiedOffersTheIdentifierValue() { - - Identifier.Specified identifier = Identifier.of("x"); - - assertThat(identifier.getValue()).isEqualTo("x"); - assertThat((Optional) identifier.getOptionalValue()).contains("x"); - } - - @Test - public void indentifierOfNullHasEmptyValue() { - - Identifier identifier = Identifier.ofNullable(null); - - assertThat(identifier.getOptionalValue()).isEmpty(); - } - - @SuppressWarnings("unchecked") - @Test - public void indentifierOfXHasValueX() { - - Identifier identifier = Identifier.ofNullable("x"); - - assertThat((Optional) identifier.getOptionalValue()).hasValue("x"); - } -}