Allow disabling entity lifecycle events.
We now support disabling lifecycle events through the Template API to reduce the framework overhead when events are not needed. Closes #1291
This commit is contained in:
@@ -34,6 +34,7 @@ import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
|
||||
import org.springframework.data.jdbc.core.convert.JdbcConverter;
|
||||
import org.springframework.data.mapping.IdentifierAccessor;
|
||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||
import org.springframework.data.relational.core.EntityLifecycleEventDelegate;
|
||||
import org.springframework.data.relational.core.conversion.AggregateChange;
|
||||
import org.springframework.data.relational.core.conversion.BatchingAggregateChange;
|
||||
import org.springframework.data.relational.core.conversion.DeleteAggregateChange;
|
||||
@@ -67,7 +68,7 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class JdbcAggregateTemplate implements JdbcAggregateOperations {
|
||||
|
||||
private final ApplicationEventPublisher publisher;
|
||||
private final EntityLifecycleEventDelegate eventDelegate = new EntityLifecycleEventDelegate();
|
||||
private final RelationalMappingContext context;
|
||||
|
||||
private final RelationalEntityDeleteWriter jdbcEntityDeleteWriter;
|
||||
@@ -95,7 +96,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
|
||||
Assert.notNull(converter, "RelationalConverter must not be null");
|
||||
Assert.notNull(dataAccessStrategy, "DataAccessStrategy must not be null");
|
||||
|
||||
this.publisher = publisher;
|
||||
this.eventDelegate.setPublisher(publisher);
|
||||
this.context = context;
|
||||
this.accessStrategy = dataAccessStrategy;
|
||||
this.converter = converter;
|
||||
@@ -123,7 +124,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
|
||||
Assert.notNull(converter, "RelationalConverter must not be null");
|
||||
Assert.notNull(dataAccessStrategy, "DataAccessStrategy must not be null");
|
||||
|
||||
this.publisher = publisher;
|
||||
this.eventDelegate.setPublisher(publisher);
|
||||
this.context = context;
|
||||
this.accessStrategy = dataAccessStrategy;
|
||||
this.converter = converter;
|
||||
@@ -145,6 +146,18 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
|
||||
this.entityCallbacks = entityCallbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure whether lifecycle events such as {@link AfterSaveEvent}, {@link BeforeSaveEvent}, etc. should be
|
||||
* published or whether emission should be suppressed. Enabled by default.
|
||||
*
|
||||
* @param enabled {@code true} to enable entity lifecycle events; {@code false} to disable entity lifecycle events.
|
||||
* @since 3.0
|
||||
* @see AbstractRelationalEvent
|
||||
*/
|
||||
public void setEntityLifecycleEventsEnabled(boolean enabled) {
|
||||
this.eventDelegate.setEventsEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T save(T instance) {
|
||||
|
||||
@@ -529,34 +542,32 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
|
||||
|
||||
private <T> T triggerAfterConvert(T entity) {
|
||||
|
||||
publisher.publishEvent(new AfterConvertEvent<>(entity));
|
||||
eventDelegate.publishEvent(() -> new AfterConvertEvent<>(entity));
|
||||
return entityCallbacks.callback(AfterConvertCallback.class, entity);
|
||||
}
|
||||
|
||||
private <T> T triggerBeforeConvert(T aggregateRoot) {
|
||||
|
||||
publisher.publishEvent(new BeforeConvertEvent<>(aggregateRoot));
|
||||
|
||||
eventDelegate.publishEvent(() -> new BeforeConvertEvent<>(aggregateRoot));
|
||||
return entityCallbacks.callback(BeforeConvertCallback.class, aggregateRoot);
|
||||
}
|
||||
|
||||
private <T> T triggerBeforeSave(T aggregateRoot, AggregateChange<T> change) {
|
||||
|
||||
publisher.publishEvent(new BeforeSaveEvent<>(aggregateRoot, change));
|
||||
eventDelegate.publishEvent(() -> new BeforeSaveEvent<>(aggregateRoot, change));
|
||||
|
||||
return entityCallbacks.callback(BeforeSaveCallback.class, aggregateRoot, change);
|
||||
}
|
||||
|
||||
private <T> T triggerAfterSave(T aggregateRoot, AggregateChange<T> change) {
|
||||
|
||||
publisher.publishEvent(new AfterSaveEvent<>(aggregateRoot, change));
|
||||
|
||||
eventDelegate.publishEvent(() -> new AfterSaveEvent<>(aggregateRoot, change));
|
||||
return entityCallbacks.callback(AfterSaveCallback.class, aggregateRoot);
|
||||
}
|
||||
|
||||
private <T> void triggerAfterDelete(@Nullable T aggregateRoot, Object id, AggregateChange<T> change) {
|
||||
|
||||
publisher.publishEvent(new AfterDeleteEvent<>(Identifier.of(id), aggregateRoot, change));
|
||||
eventDelegate.publishEvent(() -> new AfterDeleteEvent<>(Identifier.of(id), aggregateRoot, change));
|
||||
|
||||
if (aggregateRoot != null) {
|
||||
entityCallbacks.callback(AfterDeleteCallback.class, aggregateRoot);
|
||||
@@ -566,7 +577,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
|
||||
@Nullable
|
||||
private <T> T triggerBeforeDelete(@Nullable T aggregateRoot, Object id, MutableAggregateChange<T> change) {
|
||||
|
||||
publisher.publishEvent(new BeforeDeleteEvent<>(Identifier.of(id), aggregateRoot, change));
|
||||
eventDelegate.publishEvent(() -> new BeforeDeleteEvent<>(Identifier.of(id), aggregateRoot, change));
|
||||
|
||||
if (aggregateRoot != null) {
|
||||
return entityCallbacks.callback(BeforeDeleteCallback.class, aggregateRoot, change);
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
@@ -62,7 +63,7 @@ import org.springframework.data.relational.core.mapping.event.BeforeSaveCallback
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class JdbcAggregateTemplateUnitTests {
|
||||
|
||||
JdbcAggregateOperations template;
|
||||
JdbcAggregateTemplate template;
|
||||
|
||||
@Mock DataAccessStrategy dataAccessStrategy;
|
||||
@Mock ApplicationEventPublisher eventPublisher;
|
||||
@@ -97,7 +98,7 @@ public class JdbcAggregateTemplateUnitTests {
|
||||
assertThat(template.findAllById(emptyList(), SampleEntity.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-393
|
||||
@Test // DATAJDBC-393, GH-1291
|
||||
public void callbackOnSave() {
|
||||
|
||||
SampleEntity first = new SampleEntity(null, "Alfred");
|
||||
@@ -112,6 +113,22 @@ public class JdbcAggregateTemplateUnitTests {
|
||||
verify(callbacks).callback(eq(BeforeSaveCallback.class), eq(second), any(MutableAggregateChange.class));
|
||||
verify(callbacks).callback(AfterSaveCallback.class, third);
|
||||
assertThat(last).isEqualTo(third);
|
||||
verify(eventPublisher, times(3)).publishEvent(any(Object.class));
|
||||
}
|
||||
|
||||
@Test // GH-1291
|
||||
public void doesNotEmitEvents() {
|
||||
|
||||
SampleEntity first = new SampleEntity(null, "Alfred");
|
||||
SampleEntity second = new SampleEntity(23L, "Alfred E.");
|
||||
SampleEntity third = new SampleEntity(23L, "Neumann");
|
||||
|
||||
when(callbacks.callback(any(Class.class), any(), any())).thenReturn(second, third);
|
||||
|
||||
template.setEntityLifecycleEventsEnabled(false);
|
||||
template.save(first);
|
||||
|
||||
verifyNoInteractions(eventPublisher);
|
||||
}
|
||||
|
||||
@Test // GH-1137
|
||||
|
||||
Reference in New Issue
Block a user