DATAMONGO-379 - Improved entity instantiation.
Huge refactoring of the way MappingMongoConverter instantiates entities. The constructor arguments now have to mirror a property exactly in terms of name. Thus we can pick up mapping information from the property to lookup the correct value from the source document. The @Value annotation can be used to either inject completely arbitrary values into the instance (e.g. by referring to a Spring bean) or simply define an expression against DBObject's fields:
class Sample {
String foo;
String bar;
Sample(String foo, @Value("#root._bar") String bar) {
this.foo = foo;
this.bar = bar;
}
}
trying to create an instance of this class from
{ "foo" : "FOO" } -> new Sample("FOO", null)
{ "_bar" : "BAR" } -> new Sample(null, "BAR").
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* {@link PropertyAccessor} to allow entity based field access to {@link DBObject}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class DBObjectPropertyAccessor extends MapAccessor {
|
||||
|
||||
static MapAccessor INSTANCE = new DBObjectPropertyAccessor();
|
||||
|
||||
@Override
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class[] { DBObject.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) {
|
||||
|
||||
Map<String, Object> source = (Map<String, Object>) target;
|
||||
|
||||
Object value = source.get(name);
|
||||
return value == null ? TypedValue.NULL : new TypedValue(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PreferredConstructor;
|
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter;
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstraction for a {@link PreferredConstructor} alongside mapping information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class MappedConstructor {
|
||||
|
||||
private final Set<MappedConstructor.MappedParameter> parameters;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappedConstructor} from the given {@link MongoPersistentEntity} and {@link MappingContext}.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
public MappedConstructor(MongoPersistentEntity<?> entity,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
|
||||
|
||||
Assert.notNull(entity);
|
||||
Assert.notNull(context);
|
||||
|
||||
this.parameters = new HashSet<MappedConstructor.MappedParameter>();
|
||||
|
||||
for (Parameter<?> parameter : entity.getPreferredConstructor().getParameters()) {
|
||||
parameters.add(new MappedParameter(parameter, entity, context));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PersistentProperty} is referenced in a constructor argument of the
|
||||
* {@link PersistentEntity} backing this {@link MappedConstructor}.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public boolean isConstructorParameter(PersistentProperty<?> property) {
|
||||
|
||||
Assert.notNull(property);
|
||||
|
||||
for (MappedConstructor.MappedParameter parameter : parameters) {
|
||||
if (parameter.maps(property)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MappedParameter} for the given {@link Parameter}.
|
||||
*
|
||||
* @param parameter must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public MappedParameter getFor(Parameter<?> parameter) {
|
||||
|
||||
for (MappedParameter mappedParameter : parameters) {
|
||||
if (mappedParameter.parameter.equals(parameter)) {
|
||||
return mappedParameter;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format("Didn't find a MappedParameter for %s!", parameter.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstraction of a {@link Parameter} alongside mapping information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class MappedParameter {
|
||||
|
||||
private final MongoPersistentProperty property;
|
||||
private final Parameter<?> parameter;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappedParameter} for the given {@link Parameter}, {@link MongoPersistentProperty} and
|
||||
* {@link MappingContext}.
|
||||
*
|
||||
* @param parameter must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
public MappedParameter(Parameter<?> parameter, MongoPersistentEntity<?> entity,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, ? extends MongoPersistentProperty> context) {
|
||||
|
||||
Assert.notNull(parameter);
|
||||
Assert.notNull(entity);
|
||||
Assert.notNull(context);
|
||||
|
||||
this.parameter = parameter;
|
||||
|
||||
PropertyPath propertyPath = PropertyPath.from(parameter.getName(), entity.getType());
|
||||
PersistentPropertyPath<? extends MongoPersistentProperty> path = context.getPersistentPropertyPath(propertyPath);
|
||||
this.property = path == null ? null : path.getLeafProperty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is a SpEL expression configured for this parameter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasSpELExpression() {
|
||||
return parameter.getKey() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field name to be used to lookup the value which in turn shall be converted into the constructor
|
||||
* parameter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return property.getFieldName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the property backing the {@link Parameter}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public TypeInformation<?> getPropertyTypeInformation() {
|
||||
return property.getTypeInformation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PersistentProperty} is mapped by the parameter.
|
||||
*
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
public boolean maps(PersistentProperty<?> property) {
|
||||
return this.property.equals(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.data.convert.TypeMapper;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
import org.springframework.data.mapping.PreferredConstructor;
|
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
@@ -189,52 +189,17 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final DBObject dbo) {
|
||||
|
||||
final StandardEvaluationContext spelCtx = new StandardEvaluationContext();
|
||||
if (null != applicationContext) {
|
||||
final StandardEvaluationContext spelCtx = new StandardEvaluationContext(dbo);
|
||||
spelCtx.addPropertyAccessor(DBObjectPropertyAccessor.INSTANCE);
|
||||
|
||||
if (applicationContext != null) {
|
||||
spelCtx.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
}
|
||||
if (!(dbo instanceof BasicDBList)) {
|
||||
String[] keySet = dbo.keySet().toArray(new String[dbo.keySet().size()]);
|
||||
for (String key : keySet) {
|
||||
spelCtx.setVariable(key, dbo.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
final List<String> ctorParamNames = new ArrayList<String>();
|
||||
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
final MappedConstructor constructor = new MappedConstructor(entity, mappingContext);
|
||||
|
||||
ParameterValueProvider provider = new SpELAwareParameterValueProvider(spelExpressionParser, spelCtx) {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getParameterValue(PreferredConstructor.Parameter<T> parameter) {
|
||||
|
||||
if (parameter.getKey() != null) {
|
||||
return super.getParameterValue(parameter);
|
||||
}
|
||||
|
||||
String name = parameter.getName();
|
||||
TypeInformation<T> type = parameter.getType();
|
||||
Class<T> rawType = parameter.getRawType();
|
||||
String key = idProperty == null ? name : idProperty.getName().equals(name) ? idProperty.getFieldName() : name;
|
||||
Object obj = dbo.get(key);
|
||||
|
||||
ctorParamNames.add(name);
|
||||
if (obj instanceof DBRef) {
|
||||
return read(type, ((DBRef) obj).fetch());
|
||||
} else if (obj instanceof BasicDBList) {
|
||||
BasicDBList objAsDbList = (BasicDBList) obj;
|
||||
return conversionService.convert(readCollectionOrArray(type, objAsDbList), rawType);
|
||||
} else if (obj instanceof DBObject) {
|
||||
return read(type, ((DBObject) obj));
|
||||
} else if (null != obj && obj.getClass().isAssignableFrom(rawType)) {
|
||||
return (T) obj;
|
||||
} else if (null != obj) {
|
||||
return conversionService.convert(obj, rawType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
SpELAwareParameterValueProvider delegate = new SpELAwareParameterValueProvider(spelExpressionParser, spelCtx);
|
||||
ParameterValueProvider provider = new DelegatingParameterValueProvider(constructor, dbo, delegate);
|
||||
|
||||
final BeanWrapper<MongoPersistentEntity<S>, S> wrapper = BeanWrapper.create(entity, provider, conversionService);
|
||||
|
||||
@@ -242,7 +207,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
||||
|
||||
boolean isConstructorProperty = ctorParamNames.contains(prop.getName());
|
||||
boolean isConstructorProperty = constructor.isConstructorParameter(prop);
|
||||
boolean hasValueForProperty = dbo.containsField(prop.getFieldName());
|
||||
|
||||
if (!hasValueForProperty || isConstructorProperty) {
|
||||
@@ -892,4 +857,55 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
private class DelegatingParameterValueProvider implements ParameterValueProvider {
|
||||
|
||||
private final DBObject source;
|
||||
private final ParameterValueProvider delegate;
|
||||
private final MappedConstructor constructor;
|
||||
|
||||
/**
|
||||
* {@link ParameterValueProvider} to delegate source object lookup to a {@link SpELAwareParameterValueProvider} in
|
||||
* case a MappCon
|
||||
*
|
||||
* @param constructor must not be {@literal null}.
|
||||
* @param source must not be {@literal null}.
|
||||
* @param delegate must not be {@literal null}.
|
||||
*/
|
||||
public DelegatingParameterValueProvider(MappedConstructor constructor, DBObject source,
|
||||
SpELAwareParameterValueProvider delegate) {
|
||||
|
||||
Assert.notNull(constructor);
|
||||
Assert.notNull(source);
|
||||
Assert.notNull(delegate);
|
||||
|
||||
this.constructor = constructor;
|
||||
this.source = source;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.ParameterValueProvider#getParameterValue(org.springframework.data.mapping.PreferredConstructor.Parameter)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getParameterValue(Parameter<T> parameter) {
|
||||
|
||||
MappedConstructor.MappedParameter mappedParameter = constructor.getFor(parameter);
|
||||
Object value = mappedParameter.hasSpELExpression() ? delegate.getParameterValue(parameter) : source
|
||||
.get(mappedParameter.getFieldName());
|
||||
|
||||
TypeInformation<?> type = mappedParameter.getPropertyTypeInformation();
|
||||
|
||||
if (value instanceof DBRef) {
|
||||
return (T) read(type, ((DBRef) value).fetch());
|
||||
} else if (value instanceof BasicDBList) {
|
||||
return (T) getPotentiallyConvertedSimpleRead(readCollectionOrArray(type, (BasicDBList) value), type.getType());
|
||||
} else if (value instanceof DBObject) {
|
||||
return (T) read(type, (DBObject) value);
|
||||
} else {
|
||||
return (T) getPotentiallyConvertedSimpleRead(value, type.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,7 +1041,7 @@ public class MongoTemplateTests {
|
||||
List<TestClass> testClassList = mappingTemplate.find(new Query(Criteria.where("myDate").is(dateTime.toDate())),
|
||||
TestClass.class);
|
||||
assertThat(testClassList.size(), is(1));
|
||||
assertThat(testClassList.get(0).getMyDate(), is(testClass.getMyDate()));
|
||||
assertThat(testClassList.get(0).myDate, is(testClass.myDate));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1080,23 +1080,19 @@ public class MongoTemplateTests {
|
||||
assertThat(template.findOne(query(where("id").is(id)), Sample.class), is(nullValue()));
|
||||
}
|
||||
|
||||
public class Sample {
|
||||
public static class Sample {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
}
|
||||
|
||||
public class TestClass {
|
||||
static class TestClass {
|
||||
|
||||
private DateTime myDate;
|
||||
DateTime myDate;
|
||||
|
||||
@PersistenceConstructor
|
||||
public TestClass(DateTime date) {
|
||||
this.myDate = date;
|
||||
}
|
||||
|
||||
public DateTime getMyDate() {
|
||||
return myDate;
|
||||
TestClass(DateTime myDate) {
|
||||
this.myDate = myDate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,11 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.mapping.model.MappingInstantiationException;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
@@ -274,6 +276,22 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(result.firstname, is("Oliver"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolvesNestedComplexTypeForConstructorCorrectly() {
|
||||
|
||||
DBObject address = new BasicDBObject("street", "110 Southwark Street");
|
||||
address.put("city", "London");
|
||||
|
||||
BasicDBList addresses = new BasicDBList();
|
||||
addresses.add(address);
|
||||
|
||||
DBObject person = new BasicDBObject("firstname", "Oliver");
|
||||
person.put("addresses", addresses);
|
||||
|
||||
Person result = converter.read(Person.class, person);
|
||||
assertThat(result.addresses, is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-145
|
||||
*/
|
||||
@@ -873,17 +891,55 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(((Collection<Object>) contacts), hasItem(nullValue()));
|
||||
}
|
||||
|
||||
class GenericType<T> {
|
||||
/**
|
||||
* @see DATAMONGO-379
|
||||
*/
|
||||
@Test
|
||||
public void considersDefaultingExpressionsAtConstructorArguments() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject("foo", "bar");
|
||||
dbObject.put("foobar", 2.5);
|
||||
|
||||
DefaultedConstructorArgument result = converter.read(DefaultedConstructorArgument.class, dbObject);
|
||||
assertThat(result.bar, is(-1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-379
|
||||
*/
|
||||
@Test
|
||||
public void usesDocumentFieldIfReferencedInAtValue() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject("foo", "bar");
|
||||
dbObject.put("something", 37);
|
||||
dbObject.put("foobar", 2.5);
|
||||
|
||||
DefaultedConstructorArgument result = converter.read(DefaultedConstructorArgument.class, dbObject);
|
||||
assertThat(result.bar, is(37));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-379
|
||||
*/
|
||||
@Test(expected = MappingInstantiationException.class)
|
||||
public void rejectsNotFoundConstructorParameterForPrimitiveType() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject("foo", "bar");
|
||||
|
||||
converter.read(DefaultedConstructorArgument.class, dbObject);
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
|
||||
class ClassWithEnumProperty {
|
||||
static class ClassWithEnumProperty {
|
||||
|
||||
SampleEnum sampleEnum;
|
||||
List<SampleEnum> enums;
|
||||
}
|
||||
|
||||
enum SampleEnum {
|
||||
static enum SampleEnum {
|
||||
FIRST {
|
||||
@Override
|
||||
void method() {
|
||||
@@ -899,7 +955,7 @@ public class MappingMongoConverterUnitTests {
|
||||
abstract void method();
|
||||
}
|
||||
|
||||
class Address {
|
||||
static class Address {
|
||||
String street;
|
||||
String city;
|
||||
}
|
||||
@@ -908,7 +964,7 @@ public class MappingMongoConverterUnitTests {
|
||||
|
||||
}
|
||||
|
||||
public static class Person implements Contact {
|
||||
static class Person implements Contact {
|
||||
LocalDate birthDate;
|
||||
|
||||
@Field("foo")
|
||||
@@ -926,46 +982,46 @@ public class MappingMongoConverterUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithSortedMap {
|
||||
static class ClassWithSortedMap {
|
||||
SortedMap<String, String> map;
|
||||
}
|
||||
|
||||
class ClassWithMapProperty {
|
||||
static class ClassWithMapProperty {
|
||||
Map<Locale, String> map;
|
||||
Map<String, List<String>> mapOfLists;
|
||||
Map<String, Object> mapOfObjects;
|
||||
}
|
||||
|
||||
class ClassWithNestedMaps {
|
||||
static class ClassWithNestedMaps {
|
||||
Map<String, Map<String, Map<String, String>>> nestedMaps;
|
||||
}
|
||||
|
||||
class BirthDateContainer {
|
||||
static class BirthDateContainer {
|
||||
LocalDate birthDate;
|
||||
}
|
||||
|
||||
class BigDecimalContainer {
|
||||
static class BigDecimalContainer {
|
||||
BigDecimal value;
|
||||
Map<String, BigDecimal> map;
|
||||
List<BigDecimal> collection;
|
||||
}
|
||||
|
||||
class CollectionWrapper {
|
||||
static class CollectionWrapper {
|
||||
List<Contact> contacts;
|
||||
List<List<String>> strings;
|
||||
List<Map<String, Locale>> listOfMaps;
|
||||
}
|
||||
|
||||
class LocaleWrapper {
|
||||
static class LocaleWrapper {
|
||||
Locale locale;
|
||||
}
|
||||
|
||||
class ClassWithBigIntegerId {
|
||||
static class ClassWithBigIntegerId {
|
||||
@Id
|
||||
BigInteger id;
|
||||
}
|
||||
|
||||
class A<T> {
|
||||
static class A<T> {
|
||||
|
||||
String valueType;
|
||||
T value;
|
||||
@@ -976,12 +1032,25 @@ public class MappingMongoConverterUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithIntId {
|
||||
static class ClassWithIntId {
|
||||
|
||||
@Id
|
||||
int id;
|
||||
}
|
||||
|
||||
static class DefaultedConstructorArgument {
|
||||
|
||||
String foo;
|
||||
int bar;
|
||||
double foobar;
|
||||
|
||||
DefaultedConstructorArgument(String foo, @Value("#root.something ?: -1") int bar, double foobar) {
|
||||
this.foo = foo;
|
||||
this.bar = bar;
|
||||
this.foobar = foobar;
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalDateToDateConverter implements Converter<LocalDate, Date> {
|
||||
|
||||
public Date convert(LocalDate source) {
|
||||
|
||||
@@ -54,7 +54,6 @@ import com.mongodb.WriteConcern;
|
||||
* Modified from https://github.com/deftlabs/mongo-java-geospatial-example
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
*/
|
||||
public class GeoSpatialTests {
|
||||
|
||||
|
||||
@@ -20,8 +20,7 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -30,7 +29,9 @@ import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for testing the mapping works with generic types.
|
||||
@@ -85,15 +86,15 @@ public class GenericMappingTests {
|
||||
assertThat(result.container.content, is("Foo!"));
|
||||
}
|
||||
|
||||
public class StringWrapper extends Wrapper<String> {
|
||||
static class StringWrapper extends Wrapper<String> {
|
||||
|
||||
}
|
||||
|
||||
public class Wrapper<S> {
|
||||
static class Wrapper<S> {
|
||||
Container<S> container;
|
||||
}
|
||||
|
||||
public class Container<T> {
|
||||
static class Container<T> {
|
||||
T content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +28,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.types.ObjectId;
|
||||
@@ -46,12 +41,17 @@ import org.springframework.data.mongodb.MongoCollectionUtils;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoDbUtils;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@@ -511,7 +511,7 @@ public class MappingTests {
|
||||
assertThat(result.items.get(0).id, is(items.id));
|
||||
}
|
||||
|
||||
class Container {
|
||||
static class Container {
|
||||
|
||||
@Id
|
||||
final String id;
|
||||
@@ -526,7 +526,7 @@ public class MappingTests {
|
||||
List<Item> items;
|
||||
}
|
||||
|
||||
class Item {
|
||||
static class Item {
|
||||
|
||||
@Id
|
||||
final String id;
|
||||
|
||||
Reference in New Issue
Block a user