diff --git a/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java b/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java index 3079e2112..ea6486cc8 100644 --- a/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java +++ b/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java @@ -44,6 +44,8 @@ import org.springframework.util.ReflectionUtils; * will be invoked after all events have been published. * * @author Oliver Gierke + * @author Christoph Strobl + * @author Yuki Yoshida * @since 1.13 * @soundtrack Henrik Freischlader Trio - Master Plan (Openness) */ @@ -164,13 +166,14 @@ public class EventPublishingRepositoryProxyPostProcessor implements RepositoryPr } for (Object aggregateRoot : asCollection(object)) { - for (Object event : asCollection(ReflectionUtils.invokeMethod(publishingMethod, aggregateRoot))) { + Collection events = asCollection(ReflectionUtils.invokeMethod(publishingMethod, aggregateRoot)); + for (Object event : events) { publisher.publishEvent(event); } - } - if (clearingMethod != null) { - ReflectionUtils.invokeMethod(clearingMethod, object); + if (clearingMethod != null && !events.isEmpty()) { + ReflectionUtils.invokeMethod(clearingMethod, aggregateRoot); + } } } diff --git a/src/test/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessorUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessorUnitTests.java index 2e854db77..1fa71e2b9 100644 --- a/src/test/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessorUnitTests.java @@ -22,6 +22,7 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Value; import java.io.Serializable; @@ -39,6 +40,7 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.aop.framework.ProxyFactory; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.domain.AfterDomainEventPublication; import org.springframework.data.domain.DomainEvents; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.RepositoryInformation; @@ -49,6 +51,8 @@ import org.springframework.data.repository.core.support.EventPublishingRepositor * Unit tests for {@link EventPublishingRepositoryProxyPostProcessor} and contained classes. * * @author Oliver Gierke + * @author Mark Paluch + * @author Yuki Yoshida * @soundtrack Henrik Freischlader Trio - Nobody Else To Blame (Openness) */ @RunWith(MockitoJUnitRunner.class) @@ -101,6 +105,40 @@ public class EventPublishingRepositoryProxyPostProcessorUnitTests { verify(publisher, times(0)).publishEvent(any()); } + @Test // DATACMNS-1067 + public void clearEventsDoesNotExposedByEntity() { + + EventsWithClearing entity = spy(EventsWithClearing.of(Collections.emptyList())); + + EventPublishingMethod.of(EventsWithClearing.class).publishEventsFrom(entity, publisher); + + verify(entity, times(0)).clearDomainEvents(); + } + + @Test // DATACMNS-1067 + public void clearEventsExposedByEntity() { + + EventsWithClearing entity = spy(EventsWithClearing.of(Collections.singletonList(new SomeEvent()))); + + EventPublishingMethod.of(EventsWithClearing.class).publishEventsFrom(entity, publisher); + + verify(entity, times(1)).clearDomainEvents(); + } + + @Test // DATACMNS-1067 + public void clearEventsExposedByEntities() { + + EventsWithClearing firstEntity = spy(EventsWithClearing.of(Collections.emptyList())); + EventsWithClearing secondEntity = spy(EventsWithClearing.of(Collections.singletonList(new SomeEvent()))); + + Collection entities = Arrays.asList(firstEntity, secondEntity); + + EventPublishingMethod.of(EventsWithClearing.class).publishEventsFrom(entities, publisher); + + verify(firstEntity, times(0)).clearDomainEvents(); + verify(secondEntity, times(1)).clearDomainEvents(); + } + @Test // DATACMNS-928 public void doesNotCreatePublishingMethodIfNoAnnotationDetected() { assertThat(EventPublishingMethod.of(Object.class), is(nullValue())); @@ -215,6 +253,14 @@ public class EventPublishingRepositoryProxyPostProcessorUnitTests { @Getter(onMethod = @__(@DomainEvents)) Collection events; } + @RequiredArgsConstructor(staticName = "of") + static class EventsWithClearing { + @Getter(onMethod = @__(@DomainEvents)) final Collection events; + + @AfterDomainEventPublication + void clearDomainEvents() {} + } + @Value(staticConstructor = "of") static class OneEvent { @Getter(onMethod = @__(@DomainEvents)) Object event;