diff --git a/pom.xml b/pom.xml
index 366786fc6d..d46c8e5f01 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.2.0-SNAPSHOT
+ 4.2.x-4524-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index 2de4b6b635..e0182b8912 100644
--- a/spring-data-mongodb-benchmarks/pom.xml
+++ b/spring-data-mongodb-benchmarks/pom.xml
@@ -7,7 +7,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.2.0-SNAPSHOT
+ 4.2.x-4524-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index 41b81f9aa6..86eaaaa343 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -15,7 +15,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.2.0-SNAPSHOT
+ 4.2.x-4524-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index d7a9ddaa63..cece71b6e2 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.2.0-SNAPSHOT
+ 4.2.x-4524-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
index ae7bea36c3..921eed270c 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
@@ -578,7 +578,7 @@ private Object readIdValue(ConversionContext context, SpELExpressionEvaluator ev
String expression = idProperty.getSpelExpression();
Object resolvedValue = expression != null ? evaluator.evaluate(expression) : rawId;
- return resolvedValue != null ? readValue(context, resolvedValue, idProperty.getTypeInformation()) : null;
+ return resolvedValue != null ? readValue(context.forProperty(idProperty), resolvedValue, idProperty.getTypeInformation()) : null;
}
private void readProperties(ConversionContext context, MongoPersistentEntity> entity,
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java
index 0e3e6416b5..47c7a0027b 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java
@@ -37,6 +37,8 @@
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -80,6 +82,7 @@
import org.springframework.data.mongodb.core.mapping.FieldName.Type;
import org.springframework.data.mongodb.core.mapping.FieldType;
import org.springframework.data.mongodb.core.mapping.MongoField;
+import org.springframework.data.mongodb.core.mapping.MongoId;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.PersonPojoStringId;
@@ -2955,6 +2958,27 @@ void readShouldAllowDotsInMapKeyNameIfConfigured() {
assertThat(target.mapOfPersons).containsEntry("map.key.with.dots", person);
}
+ @ValueSource(classes = { ComplexIdAndNoAnnotation.class, ComplexIdAndIdAnnotation.class, ComplexIdAndMongoIdAnnotation.class, ComplexIdAndFieldAnnotation.class })
+ @ParameterizedTest // GH-4524
+ void projectShouldReadComplexIdType(Class> projectionTargetType) {
+
+ EntityProjectionIntrospector introspector = EntityProjectionIntrospector.create(converter.getProjectionFactory(),
+ EntityProjectionIntrospector.ProjectionPredicate.typeHierarchy()
+ .and((target, underlyingType) -> !converter.conversions.isSimpleType(target)),
+ mappingContext);
+
+ ComplexId idValue = ComplexId.of(101L);
+ org.bson.Document source = new org.bson.Document("_id", new org.bson.Document("innerId", idValue.innerId))
+ .append("value", "abc").append("_class", ComplexIdAndNoAnnotation.class.getName());
+
+ EntityProjection, ComplexIdAndNoAnnotation> projection = introspector.introspect(projectionTargetType,
+ ComplexIdAndNoAnnotation.class);
+
+ assertThat(converter.project(projection, source)) //
+ .isInstanceOf(projectionTargetType) //
+ .extracting("id").isEqualTo(idValue);
+ }
+
org.bson.Document write(Object source) {
org.bson.Document target = new org.bson.Document();
@@ -3219,7 +3243,33 @@ static class ClassWithComplexId {
}
static class ComplexId {
+
Long innerId;
+
+ static ComplexId of(Long value) {
+
+ ComplexId id = new ComplexId();
+ id.innerId = value;
+ return id;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+
+ if (o == this) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ComplexId complexId = (ComplexId) o;
+ return Objects.equals(innerId, complexId.innerId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(innerId);
+ }
}
static class TypWithCollectionConstructor {
@@ -4031,7 +4081,32 @@ static class WithPropertyHavingDotsInFieldName {
@Field(name = "field.name.with.dots", nameType = Type.KEY)
String value;
+ }
+
+ static class ComplexIdAndFieldAnnotation {
+
+ @Field("_id") //
+ ComplexId id;
+ String value;
+ }
+
+ static class ComplexIdAndMongoIdAnnotation {
+ @MongoId //
+ ComplexId id;
+ String value;
}
+ static class ComplexIdAndIdAnnotation {
+
+ @Id //
+ ComplexId id;
+ String value;
+ }
+
+ static class ComplexIdAndNoAnnotation {
+
+ ComplexId id;
+ String value;
+ }
}