DATAMONGO-1588 - Fix derived finder not accepting subclass of parameter type.
We now allow using sub types as arguments for derived queries. This makes it possible to use eg. a GeoJsonPoint for querying while the declared property type in the domain object remains a regular (legacy) Point. Original pull request: #435.
This commit is contained in:
committed by
Mark Paluch
parent
65da90afd8
commit
1135e90be0
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -369,8 +370,10 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T nextAs(Iterator<Object> iterator, Class<T> type) {
|
||||
|
||||
Object parameter = iterator.next();
|
||||
if (parameter.getClass().isAssignableFrom(type)) {
|
||||
|
||||
if (ClassUtils.isAssignable(type, parameter.getClass())) {
|
||||
return (T) parameter;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,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<Person> 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);
|
||||
|
||||
@@ -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;
|
||||
@@ -604,6 +606,29 @@ public class MongoQueryCreatorUnitTests {
|
||||
assertThat(query.getQueryObject().toJson(), is(query(where("username").not().regex(".*")).getQueryObject().toJson()));
|
||||
}
|
||||
|
||||
@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().containsKey("location"), is(true));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1588
|
||||
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<Person, Long> {
|
||||
|
||||
List<Person> findByLocationNearAndFirstname(Point location, Distance maxDistance, String firstname);
|
||||
@@ -622,6 +647,8 @@ public class MongoQueryCreatorUnitTests {
|
||||
Address address;
|
||||
|
||||
Address2dSphere address2dSphere;
|
||||
|
||||
Point location;
|
||||
}
|
||||
|
||||
static class Address {
|
||||
|
||||
Reference in New Issue
Block a user