Skip to content

Commit 0ad715f

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 ba559c2 commit 0ad715f

File tree

2 files changed

+76
-4
lines changed

2 files changed

+76
-4
lines changed

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,30 @@ protected DBObject asDBObject(@Nullable String key, @Nullable Object value) {
126126

127127
value = value instanceof Optional ? ((Optional) value).orElse(null) : value;
128128

129-
if (ID_KEY.equals(key)) {
130-
DBObject superIdValue = super.asDBObject(key, value);
131-
Document mappedIdValue = mapper.getMappedObject((BasicDBObject) superIdValue, Optional.empty());
132-
return (DBObject) JSON.parse(mappedIdValue.toJson());
129+
if (key.endsWith(ID_KEY)) {
130+
return convertId(key, value);
133131
}
134132

135133
return super.asDBObject(key, value instanceof Pattern ? value : toQuerydslMongoType(value));
136134
}
137135

136+
/**
137+
* Convert a given, already known to be an {@literal id} or even a nested document id, value into the according id
138+
* representation following the conversion rules of {@link QueryMapper#convertId(Object)}.
139+
*
140+
* @param key the property path to the given value.
141+
* @param idValue the raw {@literal id} value.
142+
* @return the {@literal id} representation in the required format.
143+
*/
144+
private DBObject convertId(String key, Object idValue) {
145+
146+
Object convertedId = mapper.convertId(idValue);
147+
148+
Document mappedIdValue = mapper.getMappedObject((BasicDBObject) super.asDBObject(key, convertedId),
149+
Optional.empty());
150+
return (DBObject) JSON.parse(mappedIdValue.toJson());
151+
}
152+
138153
/*
139154
* (non-Javadoc)
140155
* @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)