Browse Source

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
pull/4759/head
Christoph Strobl 2 years ago committed by Mark Paluch
parent
commit
4ca008db09
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 23
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java
  2. 44
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java

23
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java

@ -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.FieldName;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -137,10 +138,30 @@ class SpringDataMongodbSerializer extends MongodbDocumentSerializer {
return property.isIdProperty() ? key.replaceAll("." + ID_KEY + "$", "") : key; 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) { protected Object convert(@Nullable Path<?> path, @Nullable Constant<?> constant) {
if (!isReference(path)) { 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); MongoPersistentProperty property = getPropertyFor(path);

44
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java

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

Loading…
Cancel
Save