Skip to content

Commit 3785a52

Browse files
christophstroblmp911de
authored andcommitted
DATAMONGO-1998 - Fix Querydsl id handling for nested property references using ObjectId hex String representation.
We now follow the conversion rules for id properties with a valid ObjectId representation when parsing Querydsl queries. Original pull request: #567.
1 parent 41897c7 commit 3785a52

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2016 the original author or authors.
2+
* Copyright 2011-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
import java.util.Set;
2121
import java.util.regex.Pattern;
2222

23+
import com.mongodb.util.JSON;
2324
import org.springframework.data.mapping.context.MappingContext;
2425
import org.springframework.data.mongodb.core.convert.MongoConverter;
2526
import org.springframework.data.mongodb.core.convert.QueryMapper;
@@ -40,7 +41,7 @@
4041

4142
/**
4243
* Custom {@link MongodbSerializer} to take mapping information into account when building keys for constraints.
43-
*
44+
*
4445
* @author Oliver Gierke
4546
* @author Christoph Strobl
4647
*/
@@ -64,7 +65,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
6465

6566
/**
6667
* Creates a new {@link SpringDataMongodbSerializer} for the given {@link MappingContext}.
67-
*
68+
*
6869
* @param mappingContext must not be {@literal null}.
6970
*/
7071
public SpringDataMongodbSerializer(MongoConverter converter) {
@@ -115,12 +116,29 @@ protected String getKeyForPath(Path<?> expr, PathMetadata metadata) {
115116
@Override
116117
protected DBObject asDBObject(String key, Object value) {
117118

118-
if (ID_KEY.equals(key)) {
119-
return mapper.getMappedObject(super.asDBObject(key, value), null);
119+
if (key.endsWith(ID_KEY)) {
120+
return convertId(key, value);
120121
}
121122
return super.asDBObject(key, value instanceof Pattern ? value : converter.convertToMongoType(value));
122123
}
123124

125+
/**
126+
* Convert a given, already known to be an {@literal id} or even a nested document id, value into the according id
127+
* representation following the conversion rules of {@link QueryMapper#convertId(Object)}.
128+
*
129+
* @param key the property path to the given value.
130+
* @param idValue the raw {@literal id} value.
131+
* @return the {@literal id} representation in the required format.
132+
*/
133+
private DBObject convertId(String key, Object idValue) {
134+
135+
Object convertedId = mapper.convertId(idValue);
136+
137+
DBObject mappedIdValue = mapper.getMappedObject(super.asDBObject(key, convertedId),
138+
null);
139+
return (DBObject) JSON.parse(JSON.serialize(mappedIdValue));
140+
}
141+
124142
/*
125143
* (non-Javadoc)
126144
* @see com.querydsl.mongodb.MongodbSerializer#isReference(com.querydsl.core.types.Path)

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,18 @@
1818
import static org.hamcrest.CoreMatchers.*;
1919
import static org.junit.Assert.*;
2020

21+
import lombok.Data;
22+
2123
import java.util.Arrays;
2224

25+
import org.bson.types.ObjectId;
2326
import org.junit.Before;
2427
import org.junit.Test;
2528
import org.junit.runner.RunWith;
2629
import org.springframework.beans.factory.annotation.Autowired;
30+
import org.springframework.data.annotation.Id;
2731
import org.springframework.data.mongodb.core.MongoOperations;
32+
import org.springframework.data.mongodb.core.mapping.Document;
2833
import org.springframework.data.mongodb.core.query.Query;
2934
import org.springframework.data.mongodb.repository.Person;
3035
import org.springframework.data.mongodb.repository.QPerson;
@@ -49,7 +54,9 @@ public class QuerydslRepositorySupportTests {
4954
@Before
5055
public void setUp() {
5156

57+
operations.remove(new Query(), Outer.class);
5258
operations.remove(new Query(), Person.class);
59+
5360
person = new Person("Dave", "Matthews");
5461
operations.save(person);
5562

@@ -97,4 +104,54 @@ public void shouldAllowDbRefAgainstIdProperty() {
97104
assertThat(queryUsingIdField.fetchOne(), equalTo(person));
98105
assertThat(queryUsingIdField.fetchOne(), equalTo(queryUsingRefObject.fetchOne()));
99106
}
107+
108+
@Test // DATAMONGO-1998
109+
public void shouldLeaveStringIdThatIsNoValidObjectIdAsItIs() {
110+
111+
Outer outer = new Outer();
112+
outer.id = "outer-1";
113+
outer.inner = new Inner();
114+
outer.inner.id = "inner-1";
115+
outer.inner.value = "go climb a rock";
116+
117+
operations.save(outer);
118+
119+
QQuerydslRepositorySupportTests_Outer o = QQuerydslRepositorySupportTests_Outer.outer;
120+
SpringDataMongodbQuery<Outer> query = repoSupport.from(o).where(o.inner.id.eq(outer.inner.id));
121+
122+
assertThat(query.fetchOne(), equalTo(outer));
123+
}
124+
125+
@Test // DATAMONGO-1998
126+
public void shouldConvertStringIdThatIsAValidObjectIdIntoTheSuch() {
127+
128+
Outer outer = new Outer();
129+
outer.id = new ObjectId().toHexString();
130+
outer.inner = new Inner();
131+
outer.inner.id = new ObjectId().toHexString();
132+
outer.inner.value = "eat sleep workout repeat";
133+
134+
operations.save(outer);
135+
136+
QQuerydslRepositorySupportTests_Outer o = QQuerydslRepositorySupportTests_Outer.outer;
137+
SpringDataMongodbQuery<Outer> query = repoSupport.from(o).where(o.inner.id.eq(outer.inner.id));
138+
139+
assertThat(query.fetchOne(), equalTo(outer));
140+
}
141+
142+
@Data
143+
@Document
144+
public static class Outer {
145+
146+
@Id String id;
147+
Inner inner;
148+
}
149+
150+
@Data
151+
public static class Inner {
152+
153+
@Id String id;
154+
String value;
155+
156+
}
100157
}

0 commit comments

Comments
 (0)