DATAMONGO-336 - Fixed potential NullPointerException in MongoTemplate.

The execution of MongoTemplate.geoNear(…) potentially caused NullPointerExceptions in case the actual query does not return any results. The wrapping return object returns null for the result list and general statistics which we didn't shield against.
This commit is contained in:
Oliver Gierke
2011-12-21 18:47:39 +01:00
parent 9ac11e967a
commit ee33ce1571
2 changed files with 13 additions and 10 deletions

View File

@@ -86,7 +86,6 @@ import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.CommandResult;
import com.mongodb.DB;
@@ -488,6 +487,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
return geoNear(near, entityClass, determineCollectionName(entityClass));
}
@SuppressWarnings("unchecked")
public <T> GeoResults<T> geoNear(NearQuery near, Class<T> entityClass, String collectionName) {
if (near == null) {
@@ -503,7 +503,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
command.putAll(near.toDBObject());
CommandResult commandResult = executeCommand(command);
BasicDBList results = (BasicDBList) commandResult.get("results");
List<Object> results = (List<Object>) commandResult.get("results");
results = results == null ? Collections.emptyList() : results;
DbObjectCallback<GeoResult<T>> callback = new GeoNearResultDbObjectCallback<T>(new ReadDbObjectCallback<T>(
mongoConverter, entityClass), near.getMetric());
List<GeoResult<T>> result = new ArrayList<GeoResult<T>>(results.size());
@@ -512,7 +514,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
result.add(callback.doWith((DBObject) element));
}
double averageDistance = (Double) ((DBObject) commandResult.get("stats")).get("avgDistance");
DBObject stats = (DBObject) commandResult.get("stats");
double averageDistance = stats == null ? 0 : (Double) stats.get("avgDistance");
return new GeoResults<T>(result, new Distance(averageDistance, near.getMetric()));
}

View File

@@ -18,8 +18,8 @@ package org.springframework.data.mongodb.core.geo;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import java.net.UnknownHostException;
import java.util.Collection;
@@ -134,7 +134,7 @@ public class GeoSpatialTests {
@Test
public void withinBox() {
Box box = new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404));
List<Venue> venues = template.find(query(where("location").within(box)), Venue.class);
assertThat(venues.size(), is(4));
@@ -171,23 +171,23 @@ public class GeoSpatialTests {
@Test
public void searchAllData() {
Venue foundVenue = template.findOne(query(where("name").is("Penn Station")), Venue.class);
assertThat(foundVenue, is(notNullValue()));
List<Venue> venues = template.findAll(Venue.class);
assertThat(venues.size(), is(12));
Collection<?> names = (Collection<?>) parser.parseExpression("![name]").getValue(venues);
assertThat(names.size(), is(12));
}
public void indexCreated() {
List<DBObject> indexInfo = getIndexInfo(Venue.class);
LOGGER.debug(indexInfo);
assertThat(indexInfo.size(), is(2));
assertThat(indexInfo.get(1).get("name").toString(), is("location_2d"));
assertThat(indexInfo.get(1).get("ns").toString(), is("database.newyork"));