diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java index 315ac7a80..c2820727d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 the original author or authors. + * Copyright 2010-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ import org.springframework.data.repository.query.parser.Part.IgnoreCaseType; import org.springframework.data.repository.query.parser.Part.Type; import org.springframework.data.repository.query.parser.PartTree; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * Custom query creator to create Mongo criterias. @@ -367,8 +368,10 @@ class MongoQueryCreator extends AbstractQueryCreator { */ @SuppressWarnings("unchecked") private T nextAs(Iterator iterator, Class type) { + Object parameter = iterator.next(); - if (parameter.getClass().isAssignableFrom(type)) { + + if (ClassUtils.isAssignable(type, parameter.getClass())) { return (T) parameter; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java index ae2c22e5b..a5dc5a2ed 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java @@ -51,6 +51,7 @@ import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.repository.Person.Sex; import org.springframework.data.mongodb.repository.SampleEvaluationContextExtension.SampleSecurityContextHolder; @@ -272,6 +273,18 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(result, hasItem(dave)); } + @Test // DATAMONGO-1588 + public void findsPeopleByLocationNearUsingGeoJsonType() { + + GeoJsonPoint point = new GeoJsonPoint(-73.99171, 40.738868); + dave.setLocation(point); + repository.save(dave); + + List result = repository.findByLocationNear(point); + assertThat(result.size(), is(1)); + assertThat(result, hasItem(dave)); + } + @Test public void findsPeopleByLocationWithinCircle() { Point point = new Point(-73.99171, 40.738868); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java index 2fe220b73..f069e841e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java @@ -44,6 +44,8 @@ import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.MongoConverter; +import org.springframework.data.mongodb.core.geo.GeoJsonLineString; +import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.index.GeoSpatialIndexType; import org.springframework.data.mongodb.core.index.GeoSpatialIndexed; import org.springframework.data.mongodb.core.mapping.DBRef; @@ -669,6 +671,35 @@ public class MongoQueryCreatorUnitTests { assertThat(query, is(query(where("emailAddresses").in((Object) null)))); } + /** + * @see DATAMONGO-1588 + */ + @Test // DATAMONGO-1588 + public void queryShouldAcceptSubclassOfDeclaredArgument() { + + PartTree tree = new PartTree("findByLocationNear", User.class); + ConvertingParameterAccessor accessor = getAccessor(converter, new GeoJsonPoint(-74.044502D, 40.689247D)); + + Query query = new MongoQueryCreator(tree, accessor, context).createQuery(); + assertThat(query.getQueryObject().containsField("location"), is(true)); + } + + /** + * @see DATAMONGO-1588 + */ + @Test + public void queryShouldThrowExceptionWhenArgumentDoesNotMatchDeclaration() { + + expection.expect(IllegalArgumentException.class); + expection.expectMessage("Expected parameter type of " + Point.class); + + PartTree tree = new PartTree("findByLocationNear", User.class); + ConvertingParameterAccessor accessor = getAccessor(converter, + new GeoJsonLineString(new Point(-74.044502D, 40.689247D), new Point(-73.997330D, 40.730824D))); + + new MongoQueryCreator(tree, accessor, context).createQuery(); + } + interface PersonRepository extends Repository { List findByLocationNearAndFirstname(Point location, Distance maxDistance, String firstname); @@ -687,6 +718,8 @@ public class MongoQueryCreatorUnitTests { Address address; Address2dSphere address2dSphere; + + Point location; } static class Address {