From de4f1ffb7b3448a053af720d8cd5fc18dae59c4b Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 15 Jun 2015 14:18:09 +0200 Subject: [PATCH] DATACMNS-713 - PageImpl now adapts total if necessary. On a last page the total handed into a PageImpl constructor might not necessarily fit the content as there's the change of an insertion or deletion between the calculated count and the retrieval of the content. We now leniently mitigate those differences if the page created is the last page of the result. Related tickets: DATAJPA-728, DATACMNS-615. --- .../springframework/data/domain/PageImpl.java | 9 ++-- .../data/domain/PageImplUnitTests.java | 42 +++++++++++++++---- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/springframework/data/domain/PageImpl.java b/src/main/java/org/springframework/data/domain/PageImpl.java index a8537d8f8..12a80f885 100644 --- a/src/main/java/org/springframework/data/domain/PageImpl.java +++ b/src/main/java/org/springframework/data/domain/PageImpl.java @@ -18,7 +18,6 @@ package org.springframework.data.domain; import java.util.List; import org.springframework.core.convert.converter.Converter; -import org.springframework.util.Assert; /** * Basic {@code Page} implementation. @@ -38,16 +37,16 @@ public class PageImpl extends Chunk implements Page { * * @param content the content of this page, must not be {@literal null}. * @param pageable the paging information, can be {@literal null}. - * @param total the total amount of items available + * @param total the total amount of items available. The total might be adapted considering the length of the content + * given, if it is going to be the content of the last page. This is in place to mitigate inconsistencies */ public PageImpl(List content, Pageable pageable, long total) { super(content, pageable); - Assert.isTrue(total >= content.size(), "Total must not be less than the number of elements given!"); - - this.total = total; this.pageable = pageable; + this.total = pageable != null && pageable.getOffset() + pageable.getPageSize() > total + ? pageable.getOffset() + content.size() : total; } /** diff --git a/src/test/java/org/springframework/data/domain/PageImplUnitTests.java b/src/test/java/org/springframework/data/domain/PageImplUnitTests.java index ef9551bbe..ac3e76518 100644 --- a/src/test/java/org/springframework/data/domain/PageImplUnitTests.java +++ b/src/test/java/org/springframework/data/domain/PageImplUnitTests.java @@ -128,14 +128,6 @@ public class PageImplUnitTests { assertThat(page.hasPrevious(), is(false)); } - /** - * @see DATACMNS-615 - */ - @Test(expected = IllegalArgumentException.class) - public void rejectsTotalLessThanContentLength() { - new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(0, 10), 1); - } - /** * @see DATACMNS-635 */ @@ -153,4 +145,38 @@ public class PageImplUnitTests { assertThat(transformed.getContent(), hasSize(2)); assertThat(transformed.getContent(), contains(3, 3)); } + + /** + * @see DATACMNS-713 + */ + @Test + public void adaptsTotalForLastPageOnIntermediateDeletion() { + assertThat(new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(0, 5), 3).getTotalElements(), is(2L)); + } + + /** + * @see DATACMNS-713 + */ + @Test + public void adaptsTotalForLastPageOnIntermediateInsertion() { + assertThat(new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(0, 5), 1).getTotalElements(), is(2L)); + } + + /** + * @see DATACMNS-713 + */ + @Test + public void adaptsTotalForLastPageOnIntermediateDeletionOnLastPate() { + assertThat(new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(1, 10), 13).getTotalElements(), + is(12L)); + } + + /** + * @see DATACMNS-713 + */ + @Test + public void adaptsTotalForLastPageOnIntermediateInsertionOnLastPate() { + assertThat(new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(1, 10), 11).getTotalElements(), + is(12L)); + } }