From c1cf7434236e167cf568cb79a3a06d5c02947383 Mon Sep 17 00:00:00 2001 From: Swati Kumari Date: Fri, 9 Oct 2026 01:59:26 +0530 Subject: [PATCH 1/3] Avoid MongoDB $merge during transactional event archiving --- .../MongoDbEventPublicationRepository.java | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationRepository.java b/spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationRepository.java index f78887729..7c43de435 100644 --- a/spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationRepository.java +++ b/spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationRepository.java @@ -455,23 +455,24 @@ private void archiveTerminal(Collection identifiers, Instant now, Status s return; } - var aggregation = newAggregation(MongoDbEventPublication.class, + var publications = mongoTemplate.find( + query(where(ID).in(identifiers).and(COMPLETION_DATE).isNull()), + MongoDbEventPublication.class, collection); + + var archivedIdentifiers = mongoTemplate.find( + query(where(ID).in(identifiers)), MongoDbEventPublication.class, archiveCollection) + .stream() + .map(it -> it.id) + .toList(); + + publications.stream() + .filter(it -> !archivedIdentifiers.contains(it.id)) + .forEach(it -> { + it.completionDate = now; + it.status = status; + mongoTemplate.save(it, archiveCollection); + }); - match(where(ID).in(identifiers).and(COMPLETION_DATE).isNull()), - - addFields() - .addFieldWithValue(COMPLETION_DATE, now) - .addFieldWithValue(STATUS, status.name()) - .build(), - - merge() - .intoCollection(archiveCollection) - .on(ID) - .whenMatched(WhenDocumentsMatch.keepExistingDocument()) - .build()) - .withOptions(newAggregationOptions().skipOutput().build()); - - mongoTemplate.aggregate(aggregation, collection, Document.class); mongoTemplate.remove(query(where(ID).in(identifiers)), MongoDbEventPublication.class, collection); } From 56c88eda8f0a8932f398f7f93cb04b4e25007e93 Mon Sep 17 00:00:00 2001 From: Swati Kumari Date: Fri, 9 Oct 2026 01:59:31 +0530 Subject: [PATCH 2/3] Add regression coverage for MongoDB archive completion --- .../src/test/java/example/ApplicationIntegrationTests.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-modulith-examples/spring-modulith-example-epr-mongodb/src/test/java/example/ApplicationIntegrationTests.java b/spring-modulith-examples/spring-modulith-example-epr-mongodb/src/test/java/example/ApplicationIntegrationTests.java index c061dee90..d9bce8cb3 100644 --- a/spring-modulith-examples/spring-modulith-example-epr-mongodb/src/test/java/example/ApplicationIntegrationTests.java +++ b/spring-modulith-examples/spring-modulith-example-epr-mongodb/src/test/java/example/ApplicationIntegrationTests.java @@ -29,6 +29,7 @@ import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.context.annotation.Bean; import org.springframework.modulith.events.core.EventPublicationRegistry; +import org.springframework.modulith.events.support.CompletionMode; import org.springframework.modulith.test.EnableScenarios; import org.springframework.modulith.test.Scenario; import org.testcontainers.junit.jupiter.Testcontainers; @@ -44,7 +45,7 @@ * * @author Oliver Drotbohm */ -@SpringBootTest +@SpringBootTest(properties = { CompletionMode.PROPERTY + "=ARCHIVE" }) @EnableScenarios @Testcontainers(disabledWithoutDocker = true) class ApplicationIntegrationTests { @@ -63,7 +64,7 @@ static class MongoDbInfrastructureConfiguration { @Bean @ServiceConnection MongoDBContainer mongoDBContainer() { - return new MongoDBContainer("mongo:latest"); + return new MongoDBContainer("mongo:latest").withReplicaSet(); } @Bean From 82507ffc0cfa0742e78e0897260159ca5f66bea9 Mon Sep 17 00:00:00 2001 From: Swati Kumari Date: Fri, 9 Oct 2026 01:59:38 +0530 Subject: [PATCH 3/3] Remove obsolete aggregation imports --- .../events/mongodb/MongoDbEventPublicationRepository.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationRepository.java b/spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationRepository.java index 7c43de435..2890e8b8e 100644 --- a/spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationRepository.java +++ b/spring-modulith-events/spring-modulith-events-mongodb/src/main/java/org/springframework/modulith/events/mongodb/MongoDbEventPublicationRepository.java @@ -15,7 +15,6 @@ */ package org.springframework.modulith.events.mongodb; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; @@ -26,7 +25,6 @@ import java.util.Optional; import java.util.UUID; -import org.bson.Document; import org.jspecify.annotations.Nullable; import org.springframework.data.annotation.Id; import org.springframework.data.core.TypeInformation; @@ -34,7 +32,6 @@ import org.springframework.data.mongodb.core.FindAndModifyOptions; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.Fields; -import org.springframework.data.mongodb.core.aggregation.MergeOperation.WhenDocumentsMatch; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update;