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
This commit is contained in:
committed by
Christoph Strobl
parent
85aa3927a6
commit
bdfe4e99ed
@@ -1252,7 +1252,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
Mono<T> afterInsert = insertDocument(collectionName, dbDoc, initialized.getClass()).map(id -> {
|
||||
|
||||
T saved = entity.populateIdIfNecessary(id);
|
||||
maybeEmitEvent(new AfterSaveEvent<>(initialized, dbDoc, collectionName));
|
||||
maybeEmitEvent(new AfterSaveEvent<>(saved, dbDoc, collectionName));
|
||||
return saved;
|
||||
});
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import java.math.BigInteger;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@@ -85,8 +86,10 @@ import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.index.IndexField;
|
||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoId;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent;
|
||||
@@ -3511,6 +3514,44 @@ public class MongoTemplateTests {
|
||||
assertThat(document.id, is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2189
|
||||
@DirtiesContext
|
||||
public void afterSaveEventContainsSavedObjectUsingInsertAll() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
|
||||
|
||||
template.insertAll(Collections.singletonList(new ImmutableVersioned()));
|
||||
|
||||
assertThat(saved.get(), is(notNullValue()));
|
||||
assertThat(saved.get().id, is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2189
|
||||
@DirtiesContext
|
||||
public void afterSaveEventContainsSavedObjectUsingInsert() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
|
||||
|
||||
template.insert(new ImmutableVersioned());
|
||||
|
||||
assertThat(saved.get(), is(notNullValue()));
|
||||
assertThat(saved.get().id, is(notNullValue()));
|
||||
}
|
||||
|
||||
private AtomicReference<ImmutableVersioned> createAfterSaveReference() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = new AtomicReference<>();
|
||||
context.addApplicationListener(new AbstractMongoEventListener<ImmutableVersioned>() {
|
||||
|
||||
@Override
|
||||
public void onAfterSave(AfterSaveEvent<ImmutableVersioned> event) {
|
||||
saved.set(event.getSource());
|
||||
}
|
||||
});
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1509
|
||||
public void findsByGenericNestedListElements() {
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@@ -54,6 +55,7 @@ import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
@@ -71,11 +73,14 @@ import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
|
||||
import org.springframework.data.mongodb.core.index.GeospatialIndex;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.index.IndexOperationsAdapter;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.test.util.ReplicaSet;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@@ -95,6 +100,7 @@ public class ReactiveMongoTemplateTests {
|
||||
|
||||
@Autowired SimpleReactiveMongoDatabaseFactory factory;
|
||||
@Autowired ReactiveMongoTemplate template;
|
||||
@Autowired ConfigurableApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -1318,6 +1324,50 @@ public class ReactiveMongoTemplateTests {
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2189
|
||||
@DirtiesContext
|
||||
public void afterSaveEventContainsSavedObjectUsingInsert() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
|
||||
|
||||
template.insert(new ImmutableVersioned()) //
|
||||
.as(StepVerifier::create) //
|
||||
.expectNextCount(1) //
|
||||
.verifyComplete();
|
||||
|
||||
assertThat(saved.get()).isNotNull();
|
||||
assertThat(saved.get().id).isNotNull();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2189
|
||||
@DirtiesContext
|
||||
public void afterSaveEventContainsSavedObjectUsingInsertAll() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = createAfterSaveReference();
|
||||
|
||||
template.insertAll(Collections.singleton(new ImmutableVersioned())) //
|
||||
.as(StepVerifier::create) //
|
||||
.expectNextCount(1) //
|
||||
.verifyComplete();
|
||||
|
||||
assertThat(saved.get()).isNotNull();
|
||||
assertThat(saved.get().id).isNotNull();
|
||||
}
|
||||
|
||||
private AtomicReference<ImmutableVersioned> createAfterSaveReference() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = new AtomicReference<>();
|
||||
context.addApplicationListener(new AbstractMongoEventListener<ImmutableVersioned>() {
|
||||
|
||||
@Override
|
||||
public void onAfterSave(AfterSaveEvent<ImmutableVersioned> event) {
|
||||
saved.set(event.getSource());
|
||||
}
|
||||
});
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2012
|
||||
public void watchesDatabaseCorrectly() throws InterruptedException {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user