Apply type conversion to id types.

This commit makes sure to convert the generated query into the target type.

Closes #4709
Original pull request: #4721
This commit is contained in:
Christoph Strobl
2024-06-11 11:49:21 +02:00
committed by Mark Paluch
parent ad45069f50
commit 4ca008db09
2 changed files with 63 additions and 4 deletions

View File

@@ -26,6 +26,7 @@ import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.mapping.FieldName;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -137,10 +138,30 @@ class SpringDataMongodbSerializer extends MongodbDocumentSerializer {
return property.isIdProperty() ? key.replaceAll("." + ID_KEY + "$", "") : key;
}
@Override
protected boolean isId(Path<?> arg) {
MongoPersistentProperty propertyFor = getPropertyFor(arg);
return propertyFor == null ? super.isId(arg) : propertyFor.isIdProperty();
}
protected Object convert(@Nullable Path<?> path, @Nullable Constant<?> constant) {
if (!isReference(path)) {
return super.convert(path, constant);
MongoPersistentProperty property = getPropertyFor(path);
if(property == null) {
return super.convert(path, constant);
}
if(property.isIdProperty()) {
return mapper.convertId(constant.getConstant(), property.getFieldType());
}
if(property.hasExplicitWriteTarget()) {
return converter.convertToMongoType(constant.getConstant(), TypeInformation.of(property.getFieldType()));
}
return converter.convertToMongoType(constant.getConstant());
}
MongoPersistentProperty property = getPropertyFor(path);

View File

@@ -30,17 +30,21 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Id;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
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.repository.Person.Sex;
import org.springframework.data.mongodb.repository.QAddress;
import org.springframework.data.mongodb.repository.QPerson;
import org.springframework.data.mongodb.repository.User;
import com.querydsl.core.types.Ops;
import com.querydsl.core.types.Predicate;
@@ -50,7 +54,6 @@ import com.querydsl.core.types.dsl.BooleanOperation;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.core.types.dsl.SimplePath;
import com.querydsl.core.types.dsl.StringPath;
import org.springframework.data.mongodb.repository.User;
/**
* Unit tests for {@link SpringDataMongodbSerializer}.
@@ -115,7 +118,7 @@ public class SpringDataMongodbSerializerUnitTests {
}
@Test // DATAMONGO-467, DATAMONGO-1798
public void retainsIdPropertyType() {
public void appliesImplicitIdConversion() {
ObjectId id = new ObjectId();
@@ -123,7 +126,7 @@ public class SpringDataMongodbSerializerUnitTests {
StringPath idPath = builder.getString("id");
Document result = (Document) serializer.visit((BooleanOperation) idPath.eq(id.toString()), null);
assertThat(result.get("_id")).isNotNull().isInstanceOf(String.class).isEqualTo(id.toString());
assertThat(result.get("_id")).isNotNull().isInstanceOf(ObjectId.class);
}
@Test // DATAMONGO-761
@@ -246,6 +249,41 @@ public class SpringDataMongodbSerializerUnitTests {
assertThat(serializer.handle(predicate)).isEqualTo(Document.parse("{ 'spiritAnimal' : '007' }"));
}
@Test // GH-4709
void appliesConversionToIdType() {
Predicate predicate = QSpringDataMongodbSerializerUnitTests_Outer.outer.embeddedObject.id
.eq("64268a7b17ac6a00018bf312");
assertThat(serializer.handle(predicate))
.isEqualTo(new Document("embedded_object._id", new ObjectId("64268a7b17ac6a00018bf312")));
}
@Test // GH-4709
void appliesConversionToIdTypeForExplicitTypeRef() {
Predicate predicate = QQuerydslRepositorySupportTests_WithMongoId.withMongoId.id.eq("64268a7b17ac6a00018bf312");
assertThat(serializer.handle(predicate)).isEqualTo(new Document("_id", "64268a7b17ac6a00018bf312"));
}
@org.springframework.data.mongodb.core.mapping.Document(collection = "record")
class Outer {
@Id private String id;
@Field("embedded_object") private Inner embeddedObject;
}
@org.springframework.data.mongodb.core.mapping.Document(collection = "embedded_object")
class Inner {
@Id private String id;
}
public class WithMongoId {
@MongoId private String id;
}
class Address {
String id;
String street;