From c82344fdb3f3ed7f520b0d599f32794f0f6688e6 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 20 Sep 2017 11:09:25 +0200 Subject: [PATCH] DATACMNS-1163 - EventPublishingInterceptor now prefers arguments over return values for event publication. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now prefer to inspect the arguments handed to save(…) methods over inspecting the return value as the invocation of the actual method is free to exchange the instance handed into it and return a completely new one with the events contained in the parameter completely wiped. --- ...ublishingRepositoryProxyPostProcessor.java | 5 +++- ...RepositoryProxyPostProcessorUnitTests.java | 25 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) 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 01a2fda29..f8efe8da8 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 @@ -89,13 +89,16 @@ public class EventPublishingRepositoryProxyPostProcessor implements RepositoryPr @Override public Object invoke(MethodInvocation invocation) throws Throwable { + Object[] arguments = invocation.getArguments(); Object result = invocation.proceed(); if (!invocation.getMethod().getName().startsWith("save")) { return result; } - eventMethod.publishEventsFrom(result, publisher); + 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 f3e5350ba..6ae8bc666 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 @@ -241,12 +241,33 @@ public class EventPublishingRepositoryProxyPostProcessorUnitTests { verify(secondEntity, times(1)).clearDomainEvents(); } + @Test // DATACMNS-1163 + public void publishesEventFromParameter() throws Throwable { + + Object event = new Object(); + MultipleEvents parameter = MultipleEvents.of(Collections.singleton(event)); + MultipleEvents returnValue = MultipleEvents.of(Collections.emptySet()); + + Method method = SampleRepository.class.getMethod("save", Object.class); + mockInvocation(invocation, method, parameter, returnValue); + + EventPublishingMethodInterceptor.of(EventPublishingMethod.of(MultipleEvents.class), publisher).invoke(invocation); + + verify(publisher, times(1)).publishEvent(event); + } + private static void mockInvocation(MethodInvocation invocation, Method method, Object parameterAndReturnValue) throws Throwable { + mockInvocation(invocation, method, parameterAndReturnValue, parameterAndReturnValue); + } + + private static void mockInvocation(MethodInvocation invocation, Method method, Object parameter, Object returnValue) + throws Throwable { + doReturn(method).when(invocation).getMethod(); - doReturn(new Object[] { parameterAndReturnValue }).when(invocation).getArguments(); - doReturn(parameterAndReturnValue).when(invocation).proceed(); + doReturn(new Object[] { parameter }).when(invocation).getArguments(); + doReturn(returnValue).when(invocation).proceed(); } @Value(staticConstructor = "of")