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.
This commit is contained in:
committed by
Mark Paluch
parent
7a2a3fb2eb
commit
22f9eded60
@@ -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<T> 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 <T> void deleteTree(Object id, @Nullable T entity, Class<T> domainType) {
|
||||
@@ -396,19 +393,15 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
|
||||
List<T> 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> T triggerAfterLoad(Object id, T entity) {
|
||||
private <T> 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> T triggerBeforeSave(T aggregateRoot, @Nullable Object id, AggregateChange<T> change) {
|
||||
private <T> T triggerBeforeSave(T aggregateRoot, AggregateChange<T> change) {
|
||||
|
||||
publisher.publishEvent(new BeforeSaveEvent( //
|
||||
Identifier.ofNullable(id), //
|
||||
//
|
||||
aggregateRoot, //
|
||||
change //
|
||||
));
|
||||
//
|
||||
change));
|
||||
|
||||
return entityCallbacks.callback(BeforeSaveCallback.class, aggregateRoot, change);
|
||||
}
|
||||
|
||||
private <T> T triggerAfterSave(T aggregateRoot, Object id, AggregateChange<T> change) {
|
||||
private <T> T triggerAfterSave(T aggregateRoot, AggregateChange<T> 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 <T> 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> 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<DummyEntity, Long> {}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@RequiredArgsConstructor
|
||||
private static class Log {
|
||||
|
||||
@Id Long id;
|
||||
DummyEntity entity;
|
||||
String text;
|
||||
}
|
||||
|
||||
private interface LogRepository extends CrudRepository<Log, Long> {}
|
||||
|
||||
@Configuration
|
||||
@Import(TestConfiguration.class)
|
||||
@EnableJdbcRepositories(considerNestedRepositories = true)
|
||||
static class Config {
|
||||
|
||||
static long lastLogId;
|
||||
|
||||
@Bean
|
||||
Class<?> testClass() {
|
||||
return JdbcRepositoryManipulateDbActionsIntegrationTests.class;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ApplicationListener<BeforeDeleteEvent> softDeleteListener() {
|
||||
|
||||
return event -> {
|
||||
|
||||
DummyEntity entity = (DummyEntity) event.getOptionalEntity().orElseThrow(AssertionFailedError::new);
|
||||
entity.deleted = true;
|
||||
|
||||
List<DbAction<?>> actions = event.getChange().getActions();
|
||||
actions.clear();
|
||||
actions.add(new DbAction.UpdateRoot<>(entity));
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
ApplicationListener<BeforeSaveEvent> 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<DbAction<?>> actions = event.getChange().getActions();
|
||||
actions.add(new DbAction.InsertRoot<>(log));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<DataAccessStrategy> 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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <T> BeforeDeleteEvent(Specified id, Optional<?> entity, AggregateChange change) {
|
||||
public <T> BeforeDeleteEvent(Identifier id, @Nullable Object entity, AggregateChange<?> change) {
|
||||
super(id, entity, change);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
private final Object value;
|
||||
|
||||
private Identifier(Object value) {
|
||||
|
||||
Assert.notNull(value, "Identifier must not be null!");
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Specified} identifier for the given, non-null value.
|
||||
* Creates a new {@link Identifier} 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) {
|
||||
public static Identifier of(Object identifier) {
|
||||
|
||||
Assert.notNull(identifier, "Identifier must not be null!");
|
||||
|
||||
return SpecifiedIdentifier.of(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces an {@link Identifier} of appropriate type depending the argument being {@code null} or not.
|
||||
*
|
||||
* @param identifier May be {@code null}.
|
||||
* @return an {@link Identifier}.
|
||||
*/
|
||||
static Identifier ofNullable(@Nullable Object identifier) {
|
||||
return identifier == null ? Unset.UNSET : of(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) {
|
||||
|
||||
/**
|
||||
* Returns the identifier value.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
default Object getValue() {
|
||||
return getOptionalValue().orElseThrow(() -> new IllegalStateException("Should not happen!"));
|
||||
}
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
Identifier that = (Identifier) o;
|
||||
return value.equals(that.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Object> getOptionalEntity();
|
||||
|
||||
@Nullable
|
||||
Object getEntity();
|
||||
}
|
||||
|
||||
@@ -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(Identifier id, Object entity, AggregateChange change) {
|
||||
super(id, Optional.of(entity), change);
|
||||
RelationalEventWithEntity(Object entity) {
|
||||
|
||||
super(entity);
|
||||
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entity to which this event refers. Guaranteed to be not {@literal null}.
|
||||
*/
|
||||
@Override
|
||||
public Object getEntity() {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<Object> 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
public interface WithAggregateChange extends RelationalEvent {
|
||||
|
||||
UNSET;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jdbc.core.mapping.event.Identifier#getOptionalValue()
|
||||
/**
|
||||
* @return Guaranteed to be not {@literal null}.
|
||||
*/
|
||||
@Override
|
||||
public Optional<Object> getOptionalValue() {
|
||||
return Optional.empty();
|
||||
}
|
||||
AggregateChange<?> getAggregateChange();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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<Object>) 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<Object>) identifier.getOptionalValue()).hasValue("x");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user