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 4d0bf006b9..1db165c2e9 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 @@ -39,15 +39,17 @@ import org.springframework.util.ReflectionUtils; /** - * {@link RepositoryProxyPostProcessor} to register a {@link MethodInterceptor} to intercept the - * {@link CrudRepository#save(Object)} method and publish events potentially exposed via a method annotated with - * {@link DomainEvents}. If no such method can be detected on the aggregate root, no interceptor is added. Additionally, + * {@link RepositoryProxyPostProcessor} to register a {@link MethodInterceptor} to intercept + * {@link CrudRepository#save(Object)} and {@link CrudRepository#delete(Object)} methods and publish events potentially + * exposed via a method annotated with {@link DomainEvents}. If no such method can be detected on the aggregate root, no + * interceptor is added. Additionally, * the aggregate root can expose a method annotated with {@link AfterDomainEventPublication}. If present, the method * will be invoked after all events have been published. * * @author Oliver Gierke * @author Christoph Strobl * @author Yuki Yoshida + * @author Réda Housni Alaoui * @since 1.13 * @soundtrack Henrik Freischlader Trio - Master Plan (Openness) */ @@ -73,7 +75,7 @@ public void postProcess(ProxyFactory factory, RepositoryInformation repositoryIn } /** - * {@link MethodInterceptor} to publish events exposed an aggregate on calls to a save method on the repository. + * {@link MethodInterceptor} to publish events exposed an aggregate on calls to a save or delete method on the repository. * * @author Oliver Gierke * @since 1.13 @@ -94,12 +96,16 @@ public Object invoke(@SuppressWarnings("null") MethodInvocation invocation) thro Object[] arguments = invocation.getArguments(); Object result = invocation.proceed(); - if (!invocation.getMethod().getName().startsWith("save")) { + String methodName = invocation.getMethod().getName(); + Object eventSource; + if (methodName.startsWith("save")) { + eventSource = arguments.length == 1 ? arguments[0] : result; + } else if ((methodName.equals("delete") || methodName.equals("deleteAll")) && arguments.length == 1) { + eventSource = arguments[0]; + } else { return result; } - Object eventSource = arguments.length == 1 ? arguments[0] : result; - eventMethod.publishEventsFrom(eventSource, publisher); return result; 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 3cf5156a0b..130a2c9a39 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 @@ -51,6 +51,7 @@ * @author Oliver Gierke * @author Mark Paluch * @author Yuki Yoshida + * @author Réda Housni Alaoui * @soundtrack Henrik Freischlader Trio - Nobody Else To Blame (Openness) */ @RunWith(MockitoJUnitRunner.Silent.class) @@ -121,7 +122,20 @@ public void interceptsSaveMethod() throws Throwable { verify(publisher).publishEvent(event); } + + @Test // DATACMNS-1663 + public void interceptsDeleteMethod() throws Throwable { + SomeEvent event = new SomeEvent(); + MultipleEvents sample = MultipleEvents.of(Collections.singletonList(event)); + mockInvocation(invocation, SampleRepository.class.getMethod("delete", Object.class), sample); + EventPublishingMethodInterceptor// + .of(EventPublishingMethod.of(MultipleEvents.class), publisher)// + .invoke(invocation); + + verify(publisher).publishEvent(event); + } + @Test // DATACMNS-928 public void doesNotInterceptNonSaveMethod() throws Throwable { @@ -134,6 +148,18 @@ public void doesNotInterceptNonSaveMethod() throws Throwable { verify(publisher, never()).publishEvent(any()); } + @Test // DATACMNS-1663 + public void doesNotInterceptDeleteByIdMethod() throws Throwable { + + doReturn(SampleRepository.class.getMethod("deleteById", Object.class)).when(invocation).getMethod(); + + EventPublishingMethodInterceptor// + .of(EventPublishingMethod.of(MultipleEvents.class), publisher)// + .invoke(invocation); + + verify(publisher, never()).publishEvent(any()); + } + @Test // DATACMNS-928 public void registersAdviceIfDomainTypeExposesEvents() { @@ -174,6 +200,20 @@ public void publishesEventsForCallToSaveWithIterable() throws Throwable { verify(publisher).publishEvent(any(SomeEvent.class)); } + @Test // DATACMNS-1663 + public void publishesEventsForCallToDeleteWithIterable() throws Throwable { + + SomeEvent event = new SomeEvent(); + MultipleEvents sample = MultipleEvents.of(Collections.singletonList(event)); + mockInvocation(invocation, SampleRepository.class.getMethod("deleteAll", Iterable.class), sample); + + EventPublishingMethodInterceptor// + .of(EventPublishingMethod.of(MultipleEvents.class), publisher)// + .invoke(invocation); + + verify(publisher).publishEvent(any(SomeEvent.class)); + } + @Test // DATACMNS-975 public void publishesEventsAfterSaveInvocation() throws Throwable {