diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java index c4274977b..31bdb45a4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java @@ -18,13 +18,12 @@ package org.springframework.data.mongodb.repository.query; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import java.util.Collections; import java.util.List; import java.util.function.Function; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.EntityInstantiators; -import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Range; import org.springframework.data.domain.Slice; @@ -39,6 +38,8 @@ import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; +import org.springframework.data.repository.support.PageableExecutionUtils; +import org.springframework.data.repository.support.PageableExecutionUtils.TotalSupplier; import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.StreamUtils; import org.springframework.data.util.TypeInformation; @@ -108,6 +109,7 @@ interface MongoQueryExecution { * {@link MongoQueryExecution} for pagination queries. * * @author Oliver Gierke + * @author Mark Paluch */ @RequiredArgsConstructor static final class PagedExecution implements MongoQueryExecution { @@ -120,29 +122,27 @@ interface MongoQueryExecution { * @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) */ @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object execute(Query query, Class type, String collection) { - - int overallLimit = query.getLimit(); - long count = operations.count(query, type, collection); - count = overallLimit != 0 ? Math.min(count, query.getLimit()) : count; + public Object execute(final Query query, final Class type, final String collection) { - boolean pageableOutOfScope = pageable.getOffset() > count; - - if (pageableOutOfScope) { - return new PageImpl(Collections.emptyList(), pageable, count); - } + final int overallLimit = query.getLimit(); // Apply raw pagination - query = query.with(pageable); + query.with(pageable); // Adjust limit if page would exceed the overall limit if (overallLimit != 0 && pageable.getOffset() + pageable.getPageSize() > overallLimit) { query.limit(overallLimit - pageable.getOffset()); } - List result = operations.find(query, type, collection); - return new PageImpl(result, pageable, count); + return PageableExecutionUtils.getPage(operations.find(query, type, collection), pageable, new TotalSupplier() { + + @Override + public long get() { + + long count = operations.count(query, type, collection); + return overallLimit != 0 ? Math.min(count, overallLimit) : count; + } + }); } } @@ -233,6 +233,12 @@ interface MongoQueryExecution { } } + /** + * {@link MongoQueryExecution} to execute geo-near queries with paging. + * + * @author Oliver Gierke + * @author Mark Paluch + */ static final class PagingGeoNearExecution extends GeoNearExecution { private final MongoOperations operations; @@ -257,14 +263,27 @@ interface MongoQueryExecution { * @return */ @Override - public Object execute(Query query, Class type, String collection) { + public Object execute(Query query, Class type, final String collection) { + + GeoResults geoResults = doExecuteQuery(query, type, collection); - ConvertingParameterAccessor parameterAccessor = new ConvertingParameterAccessor(operations.getConverter(), - accessor); - Query countQuery = mongoQuery.applyQueryMetaAttributesWhenPresent(mongoQuery.createCountQuery(parameterAccessor)); - long count = operations.count(countQuery, collection); + Page> page = PageableExecutionUtils.getPage(geoResults.getContent(), accessor.getPageable(), + new TotalSupplier() { + + @Override + public long get() { + + ConvertingParameterAccessor parameterAccessor = new ConvertingParameterAccessor(operations.getConverter(), + accessor); + Query countQuery = mongoQuery + .applyQueryMetaAttributesWhenPresent(mongoQuery.createCountQuery(parameterAccessor)); + + return operations.count(countQuery, collection); + } + }); - return new GeoPage(doExecuteQuery(query, type, collection), accessor.getPageable(), count); + // transform to GeoPage after applying optimization + return new GeoPage(geoResults, accessor.getPageable(), page.getTotalElements()); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java index 9f759617c..cb6fbc693 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-2016 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. @@ -19,7 +19,6 @@ import java.io.Serializable; import java.util.List; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; @@ -32,6 +31,8 @@ import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.querydsl.SimpleEntityPathResolver; import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.EntityMetadata; +import org.springframework.data.repository.support.PageableExecutionUtils; +import org.springframework.data.repository.support.PageableExecutionUtils.TotalSupplier; import org.springframework.util.Assert; import com.querydsl.core.types.EntityPath; @@ -46,6 +47,7 @@ import com.querydsl.mongodb.AbstractMongodbQuery; * * @author Oliver Gierke * @author Thomas Darimont + * @author Mark Paluch */ public class QueryDslMongoRepository extends SimpleMongoRepository implements QueryDslPredicateExecutor { @@ -136,13 +138,17 @@ public class QueryDslMongoRepository extends SimpleM * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, org.springframework.data.domain.Pageable) */ @Override - public Page findAll(Predicate predicate, Pageable pageable) { + public Page findAll(final Predicate predicate, Pageable pageable) { - AbstractMongodbQuery> countQuery = createQueryFor(predicate); AbstractMongodbQuery> query = createQueryFor(predicate); - return new PageImpl(applyPagination(query, pageable).fetchResults().getResults(), pageable, - countQuery.fetchCount()); + return PageableExecutionUtils.getPage(applyPagination(query, pageable).fetchResults().getResults(), pageable, new TotalSupplier() { + + @Override + public long get() { + return createQueryFor(predicate).fetchCount(); + } + }); } /* @@ -152,11 +158,15 @@ public class QueryDslMongoRepository extends SimpleM @Override public Page findAll(Pageable pageable) { - AbstractMongodbQuery> countQuery = createQuery(); AbstractMongodbQuery> query = createQuery(); - return new PageImpl(applyPagination(query, pageable).fetchResults().getResults(), pageable, - countQuery.fetchCount()); + return PageableExecutionUtils.getPage(applyPagination(query, pageable).fetchResults().getResults(), pageable, new TotalSupplier() { + + @Override + public long get() { + return createQuery().fetchCount(); + } + }); } /* diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java index 21af693ba..83665535c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java @@ -36,6 +36,8 @@ import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.query.MongoEntityInformation; +import org.springframework.data.repository.support.PageableExecutionUtils; +import org.springframework.data.repository.support.PageableExecutionUtils.TotalSupplier; import org.springframework.util.Assert; /** @@ -266,20 +268,20 @@ public class SimpleMongoRepository implements MongoR * @see org.springframework.data.mongodb.repository.MongoRepository#findAllByExample(org.springframework.data.domain.Example, org.springframework.data.domain.Pageable) */ @Override - public Page findAll(Example example, Pageable pageable) { + public Page findAll(final Example example, Pageable pageable) { Assert.notNull(example, "Sample must not be null!"); - Query q = new Query(new Criteria().alike(example)).with(pageable); + final Query q = new Query(new Criteria().alike(example)).with(pageable); - long count = mongoOperations.count(q, example.getProbeType(), entityInformation.getCollectionName()); + List list = mongoOperations.find(q, example.getProbeType(), entityInformation.getCollectionName()); + return PageableExecutionUtils.getPage(list, pageable, new TotalSupplier() { - if (count == 0) { - return new PageImpl(Collections. emptyList()); - } - - return new PageImpl(mongoOperations.find(q, example.getProbeType(), entityInformation.getCollectionName()), - pageable, count); + @Override + public long get() { + return mongoOperations.count(q, example.getProbeType(), entityInformation.getCollectionName()); + } + }); } /* 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 bdd9a1eca..84bad2d14 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 @@ -321,6 +321,7 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(page.isFirst(), is(true)); assertThat(page.isLast(), is(false)); assertThat(page.getNumberOfElements(), is(2)); + assertThat(page.getTotalElements(), is(4L)); assertThat(page, hasItems(carter, stefan)); } @@ -947,7 +948,7 @@ public abstract class AbstractPersonRepositoryIntegrationTests { } /** - * @see DATAMONGO-950 + * @see DATAMONGO-950, DATAMONGO-1464 */ @Test public void shouldNotLimitPagedQueryWhenPageRequestWithinBounds() { @@ -956,6 +957,7 @@ public abstract class AbstractPersonRepositoryIntegrationTests { new Person("Bob-3", "Dylan"), new Person("Bob-4", "Dylan"), new Person("Bob-5", "Dylan"))); Page result = repository.findTop3ByLastnameStartingWith("Dylan", new PageRequest(0, 2)); assertThat(result.getContent().size(), is(2)); + assertThat(result.getTotalElements(), is(3L)); } /** @@ -971,19 +973,20 @@ public abstract class AbstractPersonRepositoryIntegrationTests { } /** - * @see DATAMONGO-950 + * @see DATAMONGO-950, DATAMONGO-1464 */ @Test public void shouldReturnEmptyWhenPageRequestedPageIsTotallyOutOfScopeForLimit() { repository.save(Arrays.asList(new Person("Bob-1", "Dylan"), new Person("Bob-2", "Dylan"), new Person("Bob-3", "Dylan"), new Person("Bob-4", "Dylan"), new Person("Bob-5", "Dylan"))); - Page result = repository.findTop3ByLastnameStartingWith("Dylan", new PageRequest(2, 2)); + Page result = repository.findTop3ByLastnameStartingWith("Dylan", new PageRequest(100, 2)); assertThat(result.getContent().size(), is(0)); + assertThat(result.getTotalElements(), is(3L)); } /** - * @see DATAMONGO-996, DATAMONGO-950 + * @see DATAMONGO-996, DATAMONGO-950, DATAMONGO-1464 */ @Test public void gettingNonFirstPageWorksWithoutLimitBeingSet() { @@ -993,6 +996,7 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(slice.getContent(), hasSize(1)); assertThat(slice.hasPrevious(), is(true)); assertThat(slice.hasNext(), is(false)); + assertThat(slice.getTotalElements(), is(2L)); } /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java index 34e1f1793..981428dfb 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-2016 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. @@ -67,6 +67,7 @@ import com.mongodb.WriteResult; * @author Christoph Strobl * @author Oliver Gierke * @author Thomas Darimont + * @author Mark Paluch */ @RunWith(MockitoJUnitRunner.class) public class AbstractMongoQueryUnitTests { @@ -188,7 +189,7 @@ public class AbstractMongoQueryUnitTests { public void metadataShouldBeAddedToCountQueryCorrectly() { MongoQueryFake query = createQueryForMethod("findByFirstname", String.class, Pageable.class); - query.execute(new Object[] { "fake", new PageRequest(0, 10) }); + query.execute(new Object[] { "fake", new PageRequest(1, 10) }); ArgumentCaptor captor = ArgumentCaptor.forClass(Query.class); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryExecutionUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryExecutionUnitTests.java new file mode 100644 index 000000000..133e910dd --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryExecutionUnitTests.java @@ -0,0 +1,182 @@ +/* + * Copyright 2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.repository.query; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.geo.Distance; +import org.springframework.data.geo.GeoPage; +import org.springframework.data.geo.GeoResult; +import org.springframework.data.geo.GeoResults; +import org.springframework.data.geo.Metrics; +import org.springframework.data.geo.Point; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.convert.DbRefResolver; +import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; +import org.springframework.data.mongodb.core.query.NearQuery; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.repository.Person; +import org.springframework.data.mongodb.repository.query.MongoQueryExecution.PagedExecution; +import org.springframework.data.mongodb.repository.query.MongoQueryExecution.PagingGeoNearExecution; +import org.springframework.data.projection.ProjectionFactory; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.core.RepositoryMetadata; +import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; +import org.springframework.data.util.ClassTypeInformation; +import org.springframework.util.ReflectionUtils; + +/** + * Unit tests for {@link MongoQueryExecution}. + * + * @author Mark Paluch + * @soundtrack U Can't Touch This - MC Hammer + */ +@RunWith(MockitoJUnitRunner.class) +@SuppressWarnings("unchecked") +public class MongoQueryExecutionUnitTests { + + @Mock MongoOperations mongoOperationsMock; + @Mock DbRefResolver dbRefResolver; + + Point POINT = new Point(10, 20); + Distance DISTANCE = new Distance(2.5, Metrics.KILOMETERS); + RepositoryMetadata metadata = new DefaultRepositoryMetadata(PersonRepository.class); + MongoMappingContext context = new MongoMappingContext(); + ProjectionFactory factory = new SpelAwareProxyProjectionFactory(); + Method method = ReflectionUtils.findMethod(PersonRepository.class, "findByLocationNear", Point.class, Distance.class, + Pageable.class); + MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, factory, context); + + @Before + public void setUp() throws Exception { + + MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, context); + when(mongoOperationsMock.getConverter()).thenReturn(converter); + } + + /** + * @see DATAMONGO-1464 + */ + @Test + public void pagedExecutionShouldNotGenerateCountQueryIfQueryReportedNoResults() { + + when(mongoOperationsMock.find(any(Query.class), eq(Person.class), eq("person"))) + .thenReturn(Collections. emptyList()); + + PagedExecution execution = new PagedExecution(mongoOperationsMock, new PageRequest(0, 10)); + execution.execute(new Query(), Person.class, "person"); + + verify(mongoOperationsMock).find(any(Query.class), eq(Person.class), eq("person")); + verify(mongoOperationsMock, never()).count(any(Query.class), eq(Person.class), eq("person")); + } + + /** + * @see DATAMONGO-1464 + */ + @Test + public void pagedExecutionShouldUseCountFromResultWithOffsetAndResultsWithinPageSize() { + + when(mongoOperationsMock.find(any(Query.class), eq(Person.class), eq("person"))) + .thenReturn(Arrays.asList(new Person(), new Person(), new Person(), new Person())); + + PagedExecution execution = new PagedExecution(mongoOperationsMock, new PageRequest(0, 10)); + execution.execute(new Query(), Person.class, "person"); + + verify(mongoOperationsMock).find(any(Query.class), eq(Person.class), eq("person")); + verify(mongoOperationsMock, never()).count(any(Query.class), eq(Person.class), eq("person")); + } + + /** + * @see DATAMONGO-1464 + */ + @Test + public void pagedExecutionRetrievesObjectsForPageableOutOfRange() throws Exception { + + when(mongoOperationsMock.find(any(Query.class), eq(Person.class), eq("person"))) + .thenReturn(Collections. emptyList()); + + PagedExecution execution = new PagedExecution(mongoOperationsMock, new PageRequest(2, 10)); + execution.execute(new Query(), Person.class, "person"); + + verify(mongoOperationsMock).find(any(Query.class), eq(Person.class), eq("person")); + verify(mongoOperationsMock).count(any(Query.class), eq(Person.class), eq("person")); + } + + /** + * @see DATAMONGO-1464 + */ + @Test + public void pagingGeoExecutionShouldUseCountFromResultWithOffsetAndResultsWithinPageSize() throws Exception { + + MongoParameterAccessor accessor = new MongoParametersParameterAccessor(queryMethod, + new Object[] { POINT, DISTANCE, new PageRequest(0, 10) }); + + PartTreeMongoQuery query = new PartTreeMongoQuery(queryMethod, mongoOperationsMock); + GeoResult result = new GeoResult(new Person(), DISTANCE); + + when(mongoOperationsMock.geoNear(any(NearQuery.class), eq(Person.class), eq("person"))) + .thenReturn(new GeoResults(Arrays.asList(result, result, result, result))); + + PagingGeoNearExecution execution = new PagingGeoNearExecution(mongoOperationsMock, accessor, + ClassTypeInformation.fromReturnTypeOf(method), query); + execution.execute(new Query(), Person.class, "person"); + + verify(mongoOperationsMock).geoNear(any(NearQuery.class), eq(Person.class), eq("person")); + verify(mongoOperationsMock, never()).count(any(Query.class), eq("person")); + } + + /** + * @see DATAMONGO-1464 + */ + @Test + public void pagingGeoExecutionRetrievesObjectsForPageableOutOfRange() throws Exception { + + MongoParameterAccessor accessor = new MongoParametersParameterAccessor(queryMethod, + new Object[] { POINT, DISTANCE, new PageRequest(2, 10) }); + + PartTreeMongoQuery query = new PartTreeMongoQuery(queryMethod, mongoOperationsMock); + + when(mongoOperationsMock.geoNear(any(NearQuery.class), eq(Person.class), eq("person"))) + .thenReturn(new GeoResults(Collections.> emptyList())); + + PagingGeoNearExecution execution = new PagingGeoNearExecution(mongoOperationsMock, accessor, + ClassTypeInformation.fromReturnTypeOf(method), query); + execution.execute(new Query(), Person.class, "person"); + + verify(mongoOperationsMock).geoNear(any(NearQuery.class), eq(Person.class), eq("person")); + verify(mongoOperationsMock).count(any(Query.class), eq("person")); + } + + interface PersonRepository extends Repository { + + GeoPage findByLocationNear(Point point, Distance distance, Pageable pageable); + } +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java index d7221de3f..81f3661f7 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java @@ -33,17 +33,17 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Example; -import org.springframework.data.domain.ExampleMatcher.StringMatcher; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.ExampleMatcher.*; import org.springframework.data.geo.Point; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.repository.Address; import org.springframework.data.mongodb.repository.Person; -import org.springframework.data.mongodb.repository.Person.Sex; import org.springframework.data.mongodb.repository.User; +import org.springframework.data.mongodb.repository.Person.Sex; import org.springframework.data.mongodb.repository.query.MongoEntityInformation; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -174,7 +174,7 @@ public class SimpleMongoRepositoryTests { } /** - * @see DATAMONGO-1245 + * @see DATAMONGO-1245, DATAMONGO-1464 */ @Test public void findByExampleShouldLookUpEntriesCorrectly() { @@ -187,6 +187,23 @@ public class SimpleMongoRepositoryTests { assertThat(result.getContent(), hasItems(dave, oliver)); assertThat(result.getContent(), hasSize(2)); + assertThat(result.getTotalPages(), is(1)); + } + + /** + * @see DATAMONGO-1464 + */ + @Test + public void findByExampleMultiplePagesShouldLookUpEntriesCorrectly() { + + Person sample = new Person(); + sample.setLastname("Matthews"); + trimDomainType(sample, "id", "createdAt", "email"); + + Page result = repository.findAll(Example.of(sample), new PageRequest(0, 1)); + + assertThat(result.getContent(), hasSize(1)); + assertThat(result.getTotalPages(), is(2)); } /**