Skip to content

Commit 8ffa40c

Browse files
christophstroblmp911de
authored andcommitted
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
1 parent 3ad0924 commit 8ffa40c

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

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

+22-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.data.mongodb.core.mapping.FieldName;
2727
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
2828
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
29+
import org.springframework.data.util.TypeInformation;
2930
import org.springframework.lang.Nullable;
3031
import org.springframework.util.Assert;
3132
import org.springframework.util.ClassUtils;
@@ -137,10 +138,30 @@ protected String asDBKey(@Nullable Operation<?> expr, int index) {
137138
return property.isIdProperty() ? key.replaceAll("." + ID_KEY + "$", "") : key;
138139
}
139140

141+
@Override
142+
protected boolean isId(Path<?> arg) {
143+
MongoPersistentProperty propertyFor = getPropertyFor(arg);
144+
return propertyFor == null ? super.isId(arg) : propertyFor.isIdProperty();
145+
}
146+
140147
protected Object convert(@Nullable Path<?> path, @Nullable Constant<?> constant) {
141148

142149
if (!isReference(path)) {
143-
return super.convert(path, constant);
150+
151+
MongoPersistentProperty property = getPropertyFor(path);
152+
if(property == null) {
153+
return super.convert(path, constant);
154+
}
155+
156+
if(property.isIdProperty()) {
157+
return mapper.convertId(constant.getConstant(), property.getFieldType());
158+
}
159+
160+
if(property.hasExplicitWriteTarget()) {
161+
return converter.convertToMongoType(constant.getConstant(), TypeInformation.of(property.getFieldType()));
162+
}
163+
164+
return converter.convertToMongoType(constant.getConstant());
144165
}
145166

146167
MongoPersistentProperty property = getPropertyFor(path);

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

+41-3
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,21 @@
3030
import org.junit.jupiter.api.extension.ExtendWith;
3131
import org.mockito.Mock;
3232
import org.mockito.junit.jupiter.MockitoExtension;
33+
3334
import org.springframework.core.convert.converter.Converter;
35+
import org.springframework.data.annotation.Id;
3436
import org.springframework.data.convert.WritingConverter;
3537
import org.springframework.data.mongodb.core.convert.DbRefResolver;
3638
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
3739
import org.springframework.data.mongodb.core.convert.MongoConverter;
3840
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
3941
import org.springframework.data.mongodb.core.mapping.Field;
42+
import org.springframework.data.mongodb.core.mapping.MongoId;
4043
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
4144
import org.springframework.data.mongodb.repository.Person.Sex;
4245
import org.springframework.data.mongodb.repository.QAddress;
4346
import org.springframework.data.mongodb.repository.QPerson;
47+
import org.springframework.data.mongodb.repository.User;
4448

4549
import com.querydsl.core.types.Ops;
4650
import com.querydsl.core.types.Predicate;
@@ -50,7 +54,6 @@
5054
import com.querydsl.core.types.dsl.PathBuilder;
5155
import com.querydsl.core.types.dsl.SimplePath;
5256
import com.querydsl.core.types.dsl.StringPath;
53-
import org.springframework.data.mongodb.repository.User;
5457

5558
/**
5659
* Unit tests for {@link SpringDataMongodbSerializer}.
@@ -115,15 +118,15 @@ public void returnsEmptyStringIfNoPathExpressionIsGiven() {
115118
}
116119

117120
@Test // DATAMONGO-467, DATAMONGO-1798
118-
public void retainsIdPropertyType() {
121+
public void appliesImplicitIdConversion() {
119122

120123
ObjectId id = new ObjectId();
121124

122125
PathBuilder<Address> builder = new PathBuilder<Address>(Address.class, "address");
123126
StringPath idPath = builder.getString("id");
124127

125128
Document result = (Document) serializer.visit((BooleanOperation) idPath.eq(id.toString()), null);
126-
assertThat(result.get("_id")).isNotNull().isInstanceOf(String.class).isEqualTo(id.toString());
129+
assertThat(result.get("_id")).isNotNull().isInstanceOf(ObjectId.class);
127130
}
128131

129132
@Test // DATAMONGO-761
@@ -246,6 +249,41 @@ void parsesDocumentReferenceOnId() {
246249
assertThat(serializer.handle(predicate)).isEqualTo(Document.parse("{ 'spiritAnimal' : '007' }"));
247250
}
248251

252+
@Test // GH-4709
253+
void appliesConversionToIdType() {
254+
255+
Predicate predicate = QSpringDataMongodbSerializerUnitTests_Outer.outer.embeddedObject.id
256+
.eq("64268a7b17ac6a00018bf312");
257+
258+
assertThat(serializer.handle(predicate))
259+
.isEqualTo(new Document("embedded_object._id", new ObjectId("64268a7b17ac6a00018bf312")));
260+
}
261+
262+
@Test // GH-4709
263+
void appliesConversionToIdTypeForExplicitTypeRef() {
264+
265+
Predicate predicate = QQuerydslRepositorySupportTests_WithMongoId.withMongoId.id.eq("64268a7b17ac6a00018bf312");
266+
267+
assertThat(serializer.handle(predicate)).isEqualTo(new Document("_id", "64268a7b17ac6a00018bf312"));
268+
}
269+
270+
@org.springframework.data.mongodb.core.mapping.Document(collection = "record")
271+
class Outer {
272+
273+
@Id private String id;
274+
275+
@Field("embedded_object") private Inner embeddedObject;
276+
}
277+
278+
@org.springframework.data.mongodb.core.mapping.Document(collection = "embedded_object")
279+
class Inner {
280+
@Id private String id;
281+
}
282+
283+
public class WithMongoId {
284+
@MongoId private String id;
285+
}
286+
249287
class Address {
250288
String id;
251289
String street;

0 commit comments

Comments
 (0)