Skip to content

Commit 2486f16

Browse files
Fix regression in findAndReplace when using native MongoDB types as domain value.
This commit fixes a regression that prevented native org.bson.Document to serve as source for a findAndReplaceOperation. Closes: #4300 Original Pull Request: #4310
1 parent 95a05a2 commit 2486f16

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

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

+4
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ public <T> TypedOperations<T> forType(@Nullable Class<T> entityClass) {
283283
* @see EntityProjectionIntrospector#introspect(Class, Class)
284284
*/
285285
public <M, D> EntityProjection<M, D> introspectProjection(Class<M> resultType, Class<D> entityType) {
286+
287+
if (!queryMapper.getMappingContext().hasPersistentEntityFor(entityType)) {
288+
return (EntityProjection) EntityProjection.nonProjecting(resultType);
289+
}
286290
return introspector.introspect(resultType, entityType);
287291
}
288292

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

+20
Original file line numberDiff line numberDiff line change
@@ -2526,6 +2526,26 @@ public void findAndReplaceShouldProjectReturnedObjectCorrectly() {
25262526
assertThat(projection.getName()).isEqualTo("Walter");
25272527
}
25282528

2529+
@Test // GH-4300
2530+
public void findAndReplaceShouldAllowNativeDomainTypesAndReturnAProjection() {
2531+
2532+
MyPerson person = new MyPerson("Walter");
2533+
person.address = new Address("TX", "Austin");
2534+
template.save(person);
2535+
2536+
MyPerson previous = template.findAndReplace(query(where("name").is("Walter")),
2537+
new org.bson.Document("name", "Heisenberg"), FindAndReplaceOptions.options(), org.bson.Document.class,
2538+
"myPerson", MyPerson.class);
2539+
2540+
assertThat(previous).isNotNull();
2541+
assertThat(previous.getAddress()).isEqualTo(person.address);
2542+
2543+
org.bson.Document loaded = template.execute(MyPerson.class, collection -> {
2544+
return collection.find(new org.bson.Document("name", "Heisenberg")).first();
2545+
});
2546+
assertThat(loaded.get("_id")).isEqualTo(new ObjectId(person.id));
2547+
}
2548+
25292549
@Test // DATAMONGO-407
25302550
public void updatesShouldRetainTypeInformationEvenForCollections() {
25312551

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

+11
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,17 @@ void templatePassesOnTimeSeriesOptionsWhenNoTypeGiven() {
23122312
.isEqualTo(new com.mongodb.client.model.TimeSeriesOptions("time_stamp").toString());
23132313
}
23142314

2315+
@Test // GH-4300
2316+
void findAndReplaceAllowsDocumentSourceType() {
2317+
2318+
template.findAndReplace(new Query(), new Document("spring", "data"), FindAndReplaceOptions.options().upsert(),
2319+
Document.class, "coll-1", Person.class);
2320+
2321+
verify(db).getCollection(eq("coll-1"), eq(Document.class));
2322+
verify(collection).findOneAndReplace((Bson) any(Bson.class), eq(new Document("spring", "data")),
2323+
any(FindOneAndReplaceOptions.class));
2324+
}
2325+
23152326
class AutogenerateableId {
23162327

23172328
@Id BigInteger id;

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

+26
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,32 @@ void findAndReplaceShouldProjectReturnedObjectCorrectly() {
729729
}).verifyComplete();
730730
}
731731

732+
@Test // GH-4300
733+
public void findAndReplaceShouldAllowNativeDomainTypesAndReturnAProjection() {
734+
735+
MongoTemplateTests.MyPerson person = new MongoTemplateTests.MyPerson("Walter");
736+
person.address = new Address("TX", "Austin");
737+
template.save(person) //
738+
.as(StepVerifier::create) //
739+
.expectNextCount(1) //
740+
.verifyComplete();
741+
742+
template
743+
.findAndReplace(query(where("name").is("Walter")), new org.bson.Document("name", "Heisenberg"),
744+
FindAndReplaceOptions.options(), org.bson.Document.class, "myPerson", MongoTemplateTests.MyPerson.class)
745+
.as(StepVerifier::create) //
746+
.consumeNextWith(actual -> {
747+
assertThat(actual.getAddress()).isEqualTo(person.address);
748+
}).verifyComplete();
749+
750+
template.execute(MongoTemplateTests.MyPerson.class, collection -> {
751+
return collection.find(new org.bson.Document("name", "Heisenberg")).first();
752+
}).as(StepVerifier::create) //
753+
.consumeNextWith(loaded -> {
754+
assertThat(loaded.get("_id")).isEqualTo(new ObjectId(person.id));
755+
}).verifyComplete();
756+
}
757+
732758
@Test // DATAMONGO-1827
733759
void findAndReplaceShouldReplaceObjectReturingNew() {
734760

0 commit comments

Comments
 (0)