diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java index 190c83b82..7feffa28c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java @@ -20,7 +20,10 @@ import java.util.List; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.geo.Distance; import org.springframework.data.mongodb.core.geo.GeoPage; @@ -87,6 +90,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { return new GeoNearExecution(accessor).execute(query, countQuery); } else if (method.isGeoNearQuery()) { return new GeoNearExecution(accessor).execute(query); + } else if (method.isSliceQuery()) { + return new SlicedExecution(accessor.getPageable()).execute(query); } else if (method.isCollectionQuery()) { return new CollectionExecution(accessor.getPageable()).execute(query); } else if (method.isPageQuery()) { @@ -171,6 +176,41 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { } } + /** + * {@link Execution} for {@link Slice} query methods. + * + * @author Oliver Gierke + * @since 1.5 + */ + + final class SlicedExecution extends Execution { + + private final Pageable pageable; + + SlicedExecution(Pageable pageable) { + this.pageable = pageable; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query) + */ + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + Object execute(Query query) { + + MongoEntityMetadata metadata = method.getEntityInformation(); + int pageSize = pageable.getPageSize(); + Pageable slicePageable = new PageRequest(pageable.getPageNumber(), pageSize + 1, pageable.getSort()); + + List result = operations.find(query.with(slicePageable), metadata.getJavaType(), metadata.getCollectionName()); + + boolean hasNext = result.size() > pageSize; + + return new SliceImpl(hasNext ? result.subList(0, pageSize) : result, pageable, hasNext); + } + } + /** * {@link Execution} for pagination queries. * 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 a3ffd2dc7..32af2d790 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 @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2014 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. @@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mongodb.core.MongoOperations; @@ -155,8 +156,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests { public void findsPagedPersons() throws Exception { Page result = repository.findAll(new PageRequest(1, 2, Direction.ASC, "lastname", "firstname")); - assertThat(result.isFirstPage(), is(false)); - assertThat(result.isLastPage(), is(false)); + assertThat(result.isFirst(), is(false)); + assertThat(result.isLast(), is(false)); assertThat(result, hasItems(dave, stefan)); } @@ -165,8 +166,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests { Page page = repository.findByLastnameLike("*a*", new PageRequest(0, 2, Direction.ASC, "lastname", "firstname")); - assertThat(page.isFirstPage(), is(true)); - assertThat(page.isLastPage(), is(false)); + assertThat(page.isFirst(), is(true)); + assertThat(page.isLast(), is(false)); assertThat(page.getNumberOfElements(), is(2)); assertThat(page, hasItems(carter, stefan)); } @@ -176,8 +177,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests { Page page = repository.findByLastnameLikeWithPageable(".*a.*", new PageRequest(0, 2, Direction.ASC, "lastname", "firstname")); - assertThat(page.isFirstPage(), is(true)); - assertThat(page.isLastPage(), is(false)); + assertThat(page.isFirst(), is(true)); + assertThat(page.isLast(), is(false)); assertThat(page.getNumberOfElements(), is(2)); assertThat(page, hasItems(carter, stefan)); } @@ -301,8 +302,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests { Page page = repository.findAll(person.lastname.contains("a"), new PageRequest(0, 2, Direction.ASC, "lastname")); - assertThat(page.isFirstPage(), is(true)); - assertThat(page.isLastPage(), is(false)); + assertThat(page.isFirst(), is(true)); + assertThat(page.isLast(), is(false)); assertThat(page.getNumberOfElements(), is(2)); assertThat(page, hasItems(carter, stefan)); } @@ -738,4 +739,15 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(result.size(), is(1)); assertThat(result.get(0), is(dave)); } + + /** + * @see DATAMONGO-870 + */ + @Test + public void findsSliceOfPersons() { + + Slice result = repository.findByAgeGreaterThan(40, new PageRequest(0, 2, Direction.DESC, "firstname")); + + assertThat(result.hasNext(), is(true)); + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java index 52285f763..2d639e32f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2013 the original author or authors. + * Copyright 2010-2014 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. @@ -21,6 +21,7 @@ import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.geo.Box; import org.springframework.data.mongodb.core.geo.Circle; @@ -245,4 +246,8 @@ public interface PersonRepository extends MongoRepository, Query */ List findByFirstnameContainingIgnoreCase(String firstName); + /** + * @see DATAMONGO-870 + */ + Slice findByAgeGreaterThan(int age, Pageable pageable); }