From 72b927ea2c9ed4fe976e67e51a22ea7d14449c24 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 bf0324c7e..999dff22d 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 @@ -91,13 +91,16 @@ public class EventPublishingRepositoryProxyPostProcessor implements RepositoryPr @Override public Object invoke(@SuppressWarnings("null") 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 802d89130..8fb8da899 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 @@ -235,12 +235,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")