Fix id conversion for fields of complex id.

This commit fixes an issue where the property type for nested fields of an complex id is not handed over correctly leading to wrong conversion results eg. for Instant types that got then turned into ObjectIds.

Closes #4707
Original pull request: #4719
This commit is contained in:
Christoph Strobl
2024-06-10 16:24:02 +02:00
committed by Mark Paluch
parent 5cb38218d4
commit 1e32e3b0e7
3 changed files with 46 additions and 4 deletions

View File

@@ -728,7 +728,12 @@ public class QueryMapper {
} else if (isKeyword(key)) {
resultDbo.put(key, convertIdField(documentField, entry.getValue()));
} else {
resultDbo.put(key, getMappedValue(documentField, entry.getValue()));
if(documentField.getProperty() != null && documentField.getProperty().isEntity()) {
Field propertyField = createPropertyField(documentField.getPropertyEntity(), key, mappingContext);
resultDbo.put(key, getMappedValue(propertyField, entry.getValue()));
} else {
resultDbo.put(key, getMappedValue(documentField, entry.getValue()));
}
}
}

View File

@@ -1409,18 +1409,21 @@ public class MongoTemplateTests {
assertThat(result.get(0).field).isEqualTo("Beauford");
}
@Test // DATAMONGO-447
@Test // DATAMONGO-447, GH-4707
public void storesAndRemovesTypeWithComplexId() {
MyId id = new MyId();
id.id = Instant.now().minusSeconds(2);
id.first = "foo";
id.second = "bar";
id.time = Instant.now().minusSeconds(3);
TypeWithMyId source = new TypeWithMyId();
source.id = id;
template.save(source);
template.remove(query(where("id").is(id)), TypeWithMyId.class);
assertThat(template.remove(query(where("id").is(id)), TypeWithMyId.class)).extracting(DeleteResult::getDeletedCount)
.isEqualTo(1L);
}
@Test // DATAMONGO-506
@@ -2554,6 +2557,29 @@ public class MongoTemplateTests {
assertThat(projection.getName()).isEqualTo("Walter");
}
@Test // GH-4707
public void findAndReplaceUpsertsObjectWithComplexId() {
MyId id = new MyId();
id.id = Instant.now().minusSeconds(2);
id.first = "foo";
id.second = "bar";
id.time = Instant.now().minusSeconds(3);
TypeWithMyId replacement = new TypeWithMyId();
replacement.value = "spring";
template.findAndReplace(query(where("id").is(id)), replacement, FindAndReplaceOptions.options().upsert());
template.doInCollection(TypeWithMyId.class, collection -> {
org.bson.Document dbValue = collection.find(new org.bson.Document("_id.first", "foo")).first();
assertThat(dbValue).isNotNull();
assertThat(dbValue.getEmbedded(List.of("_id", "_id"), Object.class)).isInstanceOf(Date.class);
assertThat(dbValue.getEmbedded(List.of("_id", "t"), Object.class)).isInstanceOf(Date.class);
});
}
@Test // GH-4609
public void shouldReadNestedProjection() {
@@ -4397,11 +4423,15 @@ public class MongoTemplateTests {
String first;
String second;
Instant time;
@Field("t") Instant time;
}
static class TypeWithMyId {
@Id MyId id;
String value;
}
static class Sample {

View File

@@ -25,11 +25,11 @@ import org.springframework.context.ApplicationContext;
import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.util.MongoCompatibilityAdapter;
import com.mongodb.MongoWriteException;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import org.springframework.data.mongodb.util.MongoCompatibilityAdapter;
/**
* A {@link MongoTemplate} with configuration hooks and extension suitable for tests.
@@ -147,4 +147,11 @@ public class MongoTestTemplate extends MongoTemplate {
getCollection(getCollectionName(entity)).dropIndexes();
}
}
public void doInCollection(Class<?> entityClass, Consumer<MongoCollection<Document>> callback) {
execute(entityClass, (collection -> {
callback.accept(collection);
return null;
}));
}
}