DATAMONGO-1207 - Fixed potential NPE in MongoTemplate.doInsertAll(…).
If a collection containing null values is handed to MongoTempalte.insertAll(…), a NullPointerException was caused by the unguarded attempt to lookup the class of the element. We now explicitly handle this case and skip the element. Some code cleanups in MongoTemplate.doInsertAll(…).
This commit is contained in:
@@ -767,27 +767,33 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
protected <T> void doInsertAll(Collection<? extends T> listToSave, MongoWriter<T> writer) {
|
||||
Map<String, List<T>> objs = new HashMap<String, List<T>>();
|
||||
|
||||
for (T o : listToSave) {
|
||||
Map<String, List<T>> elementsByCollection = new HashMap<String, List<T>>();
|
||||
|
||||
for (T element : listToSave) {
|
||||
|
||||
if (element == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(element.getClass());
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(o.getClass());
|
||||
if (entity == null) {
|
||||
throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class "
|
||||
+ o.getClass().getName());
|
||||
throw new InvalidDataAccessApiUsageException("No PersistentEntity information found for " + element.getClass());
|
||||
}
|
||||
|
||||
String collection = entity.getCollection();
|
||||
List<T> collectionElements = elementsByCollection.get(collection);
|
||||
|
||||
List<T> objList = objs.get(collection);
|
||||
if (null == objList) {
|
||||
objList = new ArrayList<T>();
|
||||
objs.put(collection, objList);
|
||||
if (null == collectionElements) {
|
||||
collectionElements = new ArrayList<T>();
|
||||
elementsByCollection.put(collection, collectionElements);
|
||||
}
|
||||
objList.add(o);
|
||||
|
||||
collectionElements.add(element);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<T>> entry : objs.entrySet()) {
|
||||
for (Map.Entry<String, List<T>> entry : elementsByCollection.entrySet()) {
|
||||
doInsertBatch(entry.getKey(), entry.getValue(), this.mongoConverter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
@@ -188,6 +189,7 @@ public class MongoTemplateTests {
|
||||
template.dropCollection(DocumentWithDBRefCollection.class);
|
||||
template.dropCollection(SomeContent.class);
|
||||
template.dropCollection(SomeTemplate.class);
|
||||
template.dropCollection(Address.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2740,6 +2742,23 @@ public class MongoTemplateTests {
|
||||
assertThat(template.findAll(DBObject.class, "collection"), hasSize(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1207
|
||||
*/
|
||||
@Test
|
||||
public void ignoresNullElementsForInsertAll() {
|
||||
|
||||
Address newYork = new Address("NY", "New York");
|
||||
Address washington = new Address("DC", "Washington");
|
||||
|
||||
template.insertAll(Arrays.asList(newYork, null, washington));
|
||||
|
||||
List<Address> result = template.findAll(Address.class);
|
||||
|
||||
assertThat(result, hasSize(2));
|
||||
assertThat(result, hasItems(newYork, washington));
|
||||
}
|
||||
|
||||
static class DoucmentWithNamedIdField {
|
||||
|
||||
@Id String someIdKey;
|
||||
@@ -2926,6 +2945,41 @@ public class MongoTemplateTests {
|
||||
|
||||
String state;
|
||||
String city;
|
||||
|
||||
Address() {}
|
||||
|
||||
Address(String state, String city) {
|
||||
this.state = state;
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Address)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Address that = (Address) obj;
|
||||
|
||||
return ObjectUtils.nullSafeEquals(this.city, that.city) && //
|
||||
ObjectUtils.nullSafeEquals(this.state, that.state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(this.city);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(this.state);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static class VersionedPerson {
|
||||
|
||||
Reference in New Issue
Block a user