From 034a3528af66db0fde65686047d50e057e89e67c Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 11 Oct 2022 10:31:06 +0200 Subject: [PATCH] Preserve given Id on insert. This commit fixes an issue where an existing Id got replaced with a generated one when using MongoId annotation. Closes: #4184 Closes: #4197 Original pull request: #4203. --- .../data/mongodb/core/QueryOperations.java | 2 +- .../data/mongodb/core/MongoTemplateTests.java | 20 +++++++++++++++++++ .../core/QueryOperationsUnitTests.java | 9 +++++++++ .../core/ReactiveMongoTemplateTests.java | 17 ++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java index fc712461a..5a799bcbd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java @@ -272,7 +272,7 @@ class QueryOperations { */ MappedDocument prepareId(@Nullable MongoPersistentEntity entity) { - if (entity == null) { + if (entity == null || source.hasId()) { return source; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index e07149c7c..7a4d78a21 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -3636,6 +3636,26 @@ public class MongoTemplateTests { assertThat(target).isEqualTo(source); } + @Test // GH-4184 + void insertHonorsExistingRawId() { + + RawStringId source = new RawStringId(); + source.id = "abc"; + source.value = "new value"; + + template.insert(source); + + org.bson.Document result = template + .execute(db -> db.getCollection(template.getCollectionName(RawStringId.class)) + .find().limit(1).cursor().next()); + + assertThat(result).isNotNull(); + assertThat(result.get("_id")).isEqualTo("abc"); + + RawStringId target = template.findOne(query(where("id").is(source.id)), RawStringId.class); + assertThat(target).isEqualTo(source); + } + @Test // GH-4026 void saveShouldGenerateNewIdOfTypeIfExplicitlyDefined() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryOperationsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryOperationsUnitTests.java index 0a01bed2b..2d412bab8 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryOperationsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryOperationsUnitTests.java @@ -205,6 +205,15 @@ class QueryOperationsUnitTests { }); } + @Test // GH-4184 + void insertContextDoesNotOverrideExistingId() { + + assertThat(queryOperations.createInsertContext(new Document("_id", "abc")).prepareId(Person.class).getDocument())// + .satisfies(result -> { + assertThat(result).isEqualTo(new Document("_id", "abc")); + }); + } + static class Person { } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java index 0dfe01a5d..1a4e684e2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java @@ -218,6 +218,23 @@ public class ReactiveMongoTemplateTests { }).verifyComplete(); } + @Test // GH-4184 + void insertHonorsExistingRawId() { + + MongoTemplateTests.RawStringId source = new MongoTemplateTests.RawStringId(); + source.id = "abc"; + source.value = "new value"; + + template.insert(source) + .then(template.execute(db -> Flux.from( + db.getCollection(template.getCollectionName(MongoTemplateTests.RawStringId.class)).find().limit(1).first())) + .next()) + .as(StepVerifier::create).consumeNextWith(result -> { + assertThat(result).isNotNull(); + assertThat(result.get("_id")).isEqualTo("abc"); + }); + } + @Test // DATAMONGO-1444 void insertsSimpleEntityCorrectly() {