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 4e8ccc549e..34182741d7 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 @@ -47,6 +47,7 @@ * @author Christoph Strobl * @author Yuki Yoshida * @author Réda Housni Alaoui + * @author Yanming Zhou * @since 1.13 * @soundtrack Henrik Freischlader Trio - Master Plan (Openness) */ @@ -186,13 +187,13 @@ public void publishEventsFrom(@Nullable Object object, ApplicationEventPublisher return; } - for (Object aggregateRoot : asCollection(object)) { + for (Object aggregateRoot : asIterable(object)) { if (!type.isInstance(aggregateRoot)) { continue; } - for (Object event : asCollection(ReflectionUtils.invokeMethod(publishingMethod, aggregateRoot))) { + for (Object event : asIterable(ReflectionUtils.invokeMethod(publishingMethod, aggregateRoot))) { publisher.publishEvent(event); } @@ -262,21 +263,21 @@ private static Method getClearingMethod(AnnotationDetectionMethodCallback cle } /** - * Returns the given source object as collection, i.e. collections are returned as is, objects are turned into a + * Returns the given source object as iterable, i.e. iterables are returned as is, objects are turned into a * one-element collection, {@literal null} will become an empty collection. * * @param source can be {@literal null}. - * @return + * @return iterable */ @SuppressWarnings("unchecked") - private static Collection asCollection(@Nullable Object source) { + private static Iterable asIterable(@Nullable Object source) { if (source == null) { return Collections.emptyList(); } - if (Collection.class.isInstance(source)) { - return (Collection) source; + if (Iterable.class.isInstance(source)) { + return (Iterable) source; } return Collections.singletonList(source); 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 c68a958b7b..8e76d5f166 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 @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.UUID; import org.aopalliance.aop.Advice; @@ -37,6 +38,8 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.AfterDomainEventPublication; import org.springframework.data.domain.DomainEvents; +import org.springframework.data.domain.ScrollPosition; +import org.springframework.data.domain.Window; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.support.EventPublishingRepositoryProxyPostProcessor.EventPublishingMethod; @@ -49,6 +52,7 @@ * @author Mark Paluch * @author Yuki Yoshida * @author Réda Housni Alaoui + * @author Yanming Zhou * @soundtrack Henrik Freischlader Trio - Nobody Else To Blame (Openness) */ @ExtendWith(MockitoExtension.class) @@ -198,6 +202,21 @@ void publishesEventsForCallToSaveWithIterable() throws Throwable { verify(publisher).publishEvent(any(SomeEvent.class)); } + @Test + void publishesEventsForCallToSaveWithIterableAndWindowAsParameter() throws Throwable { + + var event = new SomeEvent(); + var sample = MultipleEvents.of(Collections.singletonList(event)); + Window window = Window.from(List.of(sample), ScrollPosition::offset); + mockInvocation(invocation, SampleRepository.class.getMethod("saveAll", Iterable.class), window); + + EventPublishingMethodInterceptor// + .of(EventPublishingMethod.of(MultipleEvents.class), publisher)// + .invoke(invocation); + + verify(publisher).publishEvent(any(SomeEvent.class)); + } + @Test // DATACMNS-1663 void publishesEventsForCallToDeleteWithIterable() throws Throwable {