Browse Source

DATAMONGO-505 - Fixed handling of parameter binding of associations and collection values.

Instead of converting given association values as-is, ConvertingParameterAccessor now converts each collection value into a DBRef individually.
pull/4/merge
Oliver Gierke 14 years ago
parent
commit
d7ae95a779
  1. 57
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java
  2. 72
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessorUnitTests.java

57
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java

@ -15,7 +15,11 @@ @@ -15,7 +15,11 @@
*/
package org.springframework.data.mongodb.repository.query;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
@ -25,6 +29,9 @@ import org.springframework.data.mongodb.core.geo.Point; @@ -25,6 +29,9 @@ import org.springframework.data.mongodb.core.geo.Point;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import com.mongodb.DBRef;
/**
* Custom {@link ParameterAccessor} that uses a {@link MongoWriter} to serialize parameters into Mongo format.
@ -158,7 +165,28 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor { @@ -158,7 +165,28 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
* @see org.springframework.data.mongodb.repository.ConvertingParameterAccessor.PotentiallConvertingIterator#nextConverted()
*/
public Object nextConverted(MongoPersistentProperty property) {
return property.isAssociation() ? writer.toDBRef(next(), property) : getConvertedValue(next());
Object next = next();
if (next == null) {
return null;
}
if (property.isAssociation()) {
if (next.getClass().isArray() || next instanceof Iterable) {
List<DBRef> dbRefs = new ArrayList<DBRef>();
for (Object element : asCollection(next)) {
dbRefs.add(writer.toDBRef(element, property));
}
return dbRefs;
} else {
return writer.toDBRef(next, property);
}
}
return getConvertedValue(next);
}
/*
@ -170,6 +198,33 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor { @@ -170,6 +198,33 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
}
}
/**
* Returns the given object as {@link Collection}. Will do a copy of it if it implements {@link Iterable} or is an
* array. Will return an empty {@link Collection} in case {@literal null} is given. Will wrap all other types into a
* single-element collction
*
* @param source
* @return
*/
private static Collection<?> asCollection(Object source) {
if (source instanceof Iterable) {
List<Object> result = new ArrayList<Object>();
for (Object element : (Iterable<?>) source) {
result.add(element);
}
return result;
}
if (source == null) {
return Collections.emptySet();
}
return source.getClass().isArray() ? CollectionUtils.arrayToList(source) : Collections.singleton(source);
}
/**
* Custom {@link Iterator} that adds a method to access elements in a converted manner.
*

72
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessorUnitTests.java

@ -15,11 +15,13 @@ @@ -15,11 +15,13 @@
*/
package org.springframework.data.mongodb.repository.query;
import static org.mockito.Mockito.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.mockito.Mockito.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -27,7 +29,11 @@ import org.mockito.Mock; @@ -27,7 +29,11 @@ import org.mockito.Mock;
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.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator;
import com.mongodb.BasicDBList;
@ -76,4 +82,66 @@ public class ConvertingParameterAccessorUnitTests { @@ -76,4 +82,66 @@ public class ConvertingParameterAccessorUnitTests {
assertThat(result, is((Object) reference));
}
/**
* @see DATAMONGO-505
*/
@Test
public void convertsAssociationsToDBRef() {
Property property = new Property();
property.id = 5L;
Object result = setupAndConvert(property);
assertThat(result, is(instanceOf(com.mongodb.DBRef.class)));
com.mongodb.DBRef dbRef = (com.mongodb.DBRef) result;
assertThat(dbRef.getRef(), is("property"));
assertThat(dbRef.getId(), is((Object) 5L));
}
/**
* @see DATAMONGO-505
*/
@Test
public void convertsAssociationsToDBRefForCollections() {
Property property = new Property();
property.id = 5L;
Object result = setupAndConvert(Arrays.asList(property));
assertThat(result, is(instanceOf(Collection.class)));
Collection<?> collection = (Collection<?>) result;
assertThat(collection, hasSize(1));
Object element = collection.iterator().next();
assertThat(element, is(instanceOf(com.mongodb.DBRef.class)));
com.mongodb.DBRef dbRef = (com.mongodb.DBRef) element;
assertThat(dbRef.getRef(), is("property"));
assertThat(dbRef.getId(), is((Object) 5L));
}
private Object setupAndConvert(Object... parameters) {
MongoParameterAccessor delegate = new StubParameterAccessor(parameters);
PotentiallyConvertingIterator iterator = new ConvertingParameterAccessor(converter, delegate).iterator();
MongoPersistentEntity<?> entity = context.getPersistentEntity(Entity.class);
MongoPersistentProperty property = entity.getPersistentProperty("property");
return iterator.nextConverted(property);
}
static class Entity {
@DBRef
Property property;
}
static class Property {
Long id;
}
}

Loading…
Cancel
Save