From ee33ce1571d9eee4f41fc6a3d170f33bd5e7cd5f Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 21 Dec 2011 18:47:39 +0100 Subject: [PATCH] DATAMONGO-336 - Fixed potential NullPointerException in MongoTemplate. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../data/mongodb/core/MongoTemplate.java | 9 ++++++--- .../data/mongodb/core/geo/GeoSpatialTests.java | 14 +++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index f97efb1bc..0fcf67e29 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -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 GeoResults geoNear(NearQuery near, Class 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 results = (List) commandResult.get("results"); + results = results == null ? Collections.emptyList() : results; + DbObjectCallback> callback = new GeoNearResultDbObjectCallback(new ReadDbObjectCallback( mongoConverter, entityClass), near.getMetric()); List> result = new ArrayList>(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(result, new Distance(averageDistance, near.getMetric())); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialTests.java index 54de1b381..d4f241cc3 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialTests.java +++ b/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; 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 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 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 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"));