Browse Source

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.
pull/1/head
Oliver Gierke 14 years ago
parent
commit
ee33ce1571
  1. 9
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
  2. 14
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialTests.java

9
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

@ -86,7 +86,6 @@ import org.springframework.util.Assert; @@ -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 { @@ -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 { @@ -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 { @@ -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()));
}

14
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialTests.java

@ -18,8 +18,8 @@ package org.springframework.data.mongodb.core.geo; @@ -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 { @@ -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 { @@ -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"));

Loading…
Cancel
Save