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.
This commit is contained in:
committed by
Mark Paluch
parent
41897c7d46
commit
3785a52676
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2016 the original author or authors.
|
||||
* Copyright 2011-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.mongodb.util.JSON;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
@@ -40,7 +41,7 @@ import com.querydsl.mongodb.MongodbSerializer;
|
||||
|
||||
/**
|
||||
* Custom {@link MongodbSerializer} to take mapping information into account when building keys for constraints.
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@@ -64,7 +65,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
|
||||
|
||||
/**
|
||||
* Creates a new {@link SpringDataMongodbSerializer} for the given {@link MappingContext}.
|
||||
*
|
||||
*
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
public SpringDataMongodbSerializer(MongoConverter converter) {
|
||||
@@ -115,12 +116,29 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
|
||||
@Override
|
||||
protected DBObject asDBObject(String key, Object value) {
|
||||
|
||||
if (ID_KEY.equals(key)) {
|
||||
return mapper.getMappedObject(super.asDBObject(key, value), null);
|
||||
if (key.endsWith(ID_KEY)) {
|
||||
return convertId(key, value);
|
||||
}
|
||||
return super.asDBObject(key, value instanceof Pattern ? value : converter.convertToMongoType(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a given, already known to be an {@literal id} or even a nested document id, value into the according id
|
||||
* representation following the conversion rules of {@link QueryMapper#convertId(Object)}.
|
||||
*
|
||||
* @param key the property path to the given value.
|
||||
* @param idValue the raw {@literal id} value.
|
||||
* @return the {@literal id} representation in the required format.
|
||||
*/
|
||||
private DBObject convertId(String key, Object idValue) {
|
||||
|
||||
Object convertedId = mapper.convertId(idValue);
|
||||
|
||||
DBObject mappedIdValue = mapper.getMappedObject(super.asDBObject(key, convertedId),
|
||||
null);
|
||||
return (DBObject) JSON.parse(JSON.serialize(mappedIdValue));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.querydsl.mongodb.MongodbSerializer#isReference(com.querydsl.core.types.Path)
|
||||
|
||||
@@ -18,13 +18,18 @@ package org.springframework.data.mongodb.repository.support;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.repository.Person;
|
||||
import org.springframework.data.mongodb.repository.QPerson;
|
||||
@@ -49,7 +54,9 @@ public class QuerydslRepositorySupportTests {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
operations.remove(new Query(), Outer.class);
|
||||
operations.remove(new Query(), Person.class);
|
||||
|
||||
person = new Person("Dave", "Matthews");
|
||||
operations.save(person);
|
||||
|
||||
@@ -97,4 +104,54 @@ public class QuerydslRepositorySupportTests {
|
||||
assertThat(queryUsingIdField.fetchOne(), equalTo(person));
|
||||
assertThat(queryUsingIdField.fetchOne(), equalTo(queryUsingRefObject.fetchOne()));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1998
|
||||
public void shouldLeaveStringIdThatIsNoValidObjectIdAsItIs() {
|
||||
|
||||
Outer outer = new Outer();
|
||||
outer.id = "outer-1";
|
||||
outer.inner = new Inner();
|
||||
outer.inner.id = "inner-1";
|
||||
outer.inner.value = "go climb a rock";
|
||||
|
||||
operations.save(outer);
|
||||
|
||||
QQuerydslRepositorySupportTests_Outer o = QQuerydslRepositorySupportTests_Outer.outer;
|
||||
SpringDataMongodbQuery<Outer> query = repoSupport.from(o).where(o.inner.id.eq(outer.inner.id));
|
||||
|
||||
assertThat(query.fetchOne(), equalTo(outer));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1998
|
||||
public void shouldConvertStringIdThatIsAValidObjectIdIntoTheSuch() {
|
||||
|
||||
Outer outer = new Outer();
|
||||
outer.id = new ObjectId().toHexString();
|
||||
outer.inner = new Inner();
|
||||
outer.inner.id = new ObjectId().toHexString();
|
||||
outer.inner.value = "eat sleep workout repeat";
|
||||
|
||||
operations.save(outer);
|
||||
|
||||
QQuerydslRepositorySupportTests_Outer o = QQuerydslRepositorySupportTests_Outer.outer;
|
||||
SpringDataMongodbQuery<Outer> query = repoSupport.from(o).where(o.inner.id.eq(outer.inner.id));
|
||||
|
||||
assertThat(query.fetchOne(), equalTo(outer));
|
||||
}
|
||||
|
||||
@Data
|
||||
@Document
|
||||
public static class Outer {
|
||||
|
||||
@Id String id;
|
||||
Inner inner;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Inner {
|
||||
|
||||
@Id String id;
|
||||
String value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user