Skip to content

Commit bdfe4e9

Browse files
mp911dechristophstrobl
authored andcommitted
DATAMONGO-2189 - Fix AfterSaveEvent to contain the saved entity in ReactiveMongoTemplate.insert(…).
ReactiveMongoTemplate.insert(…) now uses the saved entity when emitting AfterSaveEvent. This change affects usage of immutable objects that are using Id generation. Previously, the to-be-saved entity instance was used which left the Id unpopulated. Original Pull Request: #638
1 parent 85aa392 commit bdfe4e9

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ protected <T> Mono<T> doInsert(String collectionName, T objectToSave, MongoWrite
12521252
Mono<T> afterInsert = insertDocument(collectionName, dbDoc, initialized.getClass()).map(id -> {
12531253

12541254
T saved = entity.populateIdIfNecessary(id);
1255-
maybeEmitEvent(new AfterSaveEvent<>(initialized, dbDoc, collectionName));
1255+
maybeEmitEvent(new AfterSaveEvent<>(saved, dbDoc, collectionName));
12561256
return saved;
12571257
});
12581258

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.time.Duration;
4242
import java.time.Instant;
4343
import java.util.*;
44+
import java.util.concurrent.atomic.AtomicReference;
4445
import java.util.stream.Collectors;
4546
import java.util.stream.IntStream;
4647

@@ -85,8 +86,10 @@
8586
import org.springframework.data.mongodb.core.index.IndexField;
8687
import org.springframework.data.mongodb.core.index.IndexInfo;
8788
import org.springframework.data.mongodb.core.mapping.Field;
89+
import org.springframework.data.mongodb.core.mapping.MongoId;
8890
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
8991
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
92+
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
9093
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
9194
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
9295
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent;
@@ -3511,6 +3514,44 @@ public void onBeforeSave(BeforeSaveEvent<Document> event) {
35113514
assertThat(document.id, is(notNullValue()));
35123515
}
35133516

3517+
@Test // DATAMONGO-2189
3518+
@DirtiesContext
3519+
public void afterSaveEventContainsSavedObjectUsingInsertAll() {
3520+
3521+
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
3522+
3523+
template.insertAll(Collections.singletonList(new ImmutableVersioned()));
3524+
3525+
assertThat(saved.get(), is(notNullValue()));
3526+
assertThat(saved.get().id, is(notNullValue()));
3527+
}
3528+
3529+
@Test // DATAMONGO-2189
3530+
@DirtiesContext
3531+
public void afterSaveEventContainsSavedObjectUsingInsert() {
3532+
3533+
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
3534+
3535+
template.insert(new ImmutableVersioned());
3536+
3537+
assertThat(saved.get(), is(notNullValue()));
3538+
assertThat(saved.get().id, is(notNullValue()));
3539+
}
3540+
3541+
private AtomicReference<ImmutableVersioned> createAfterSaveReference() {
3542+
3543+
AtomicReference<ImmutableVersioned> saved = new AtomicReference<>();
3544+
context.addApplicationListener(new AbstractMongoEventListener<ImmutableVersioned>() {
3545+
3546+
@Override
3547+
public void onAfterSave(AfterSaveEvent<ImmutableVersioned> event) {
3548+
saved.set(event.getSource());
3549+
}
3550+
});
3551+
3552+
return saved;
3553+
}
3554+
35143555
@Test // DATAMONGO-1509
35153556
public void findsByGenericNestedListElements() {
35163557

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.concurrent.BlockingQueue;
4040
import java.util.concurrent.LinkedBlockingQueue;
4141
import java.util.concurrent.TimeUnit;
42+
import java.util.concurrent.atomic.AtomicReference;
4243
import java.util.stream.Collectors;
4344
import java.util.stream.IntStream;
4445

@@ -54,6 +55,7 @@
5455
import org.junit.rules.ExpectedException;
5556
import org.junit.runner.RunWith;
5657
import org.springframework.beans.factory.annotation.Autowired;
58+
import org.springframework.context.ConfigurableApplicationContext;
5759
import org.springframework.dao.DataIntegrityViolationException;
5860
import org.springframework.dao.DuplicateKeyException;
5961
import org.springframework.dao.InvalidDataAccessApiUsageException;
@@ -71,11 +73,14 @@
7173
import org.springframework.data.mongodb.core.index.GeospatialIndex;
7274
import org.springframework.data.mongodb.core.index.Index;
7375
import org.springframework.data.mongodb.core.index.IndexOperationsAdapter;
76+
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
77+
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
7478
import org.springframework.data.mongodb.core.query.Criteria;
7579
import org.springframework.data.mongodb.core.query.NearQuery;
7680
import org.springframework.data.mongodb.core.query.Query;
7781
import org.springframework.data.mongodb.core.query.Update;
7882
import org.springframework.data.mongodb.test.util.ReplicaSet;
83+
import org.springframework.test.annotation.DirtiesContext;
7984
import org.springframework.test.context.ContextConfiguration;
8085
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
8186

@@ -95,6 +100,7 @@ public class ReactiveMongoTemplateTests {
95100

96101
@Autowired SimpleReactiveMongoDatabaseFactory factory;
97102
@Autowired ReactiveMongoTemplate template;
103+
@Autowired ConfigurableApplicationContext context;
98104

99105
@Before
100106
public void setUp() {
@@ -1318,6 +1324,50 @@ public void removeShouldConsiderSkipAndSort() {
13181324
.verifyComplete();
13191325
}
13201326

1327+
@Test // DATAMONGO-2189
1328+
@DirtiesContext
1329+
public void afterSaveEventContainsSavedObjectUsingInsert() {
1330+
1331+
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
1332+
1333+
template.insert(new ImmutableVersioned()) //
1334+
.as(StepVerifier::create) //
1335+
.expectNextCount(1) //
1336+
.verifyComplete();
1337+
1338+
assertThat(saved.get()).isNotNull();
1339+
assertThat(saved.get().id).isNotNull();
1340+
}
1341+
1342+
@Test // DATAMONGO-2189
1343+
@DirtiesContext
1344+
public void afterSaveEventContainsSavedObjectUsingInsertAll() {
1345+
1346+
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
1347+
1348+
template.insertAll(Collections.singleton(new ImmutableVersioned())) //
1349+
.as(StepVerifier::create) //
1350+
.expectNextCount(1) //
1351+
.verifyComplete();
1352+
1353+
assertThat(saved.get()).isNotNull();
1354+
assertThat(saved.get().id).isNotNull();
1355+
}
1356+
1357+
private AtomicReference<ImmutableVersioned> createAfterSaveReference() {
1358+
1359+
AtomicReference<ImmutableVersioned> saved = new AtomicReference<>();
1360+
context.addApplicationListener(new AbstractMongoEventListener<ImmutableVersioned>() {
1361+
1362+
@Override
1363+
public void onAfterSave(AfterSaveEvent<ImmutableVersioned> event) {
1364+
saved.set(event.getSource());
1365+
}
1366+
});
1367+
1368+
return saved;
1369+
}
1370+
13211371
@Test // DATAMONGO-2012
13221372
public void watchesDatabaseCorrectly() throws InterruptedException {
13231373

0 commit comments

Comments
 (0)