micronaut-projects / micronaut-data

Ahead of Time Data Repositories
Apache License 2.0
465 stars 196 forks source link

Breaking behavior for Page.empty() in micronaut-data:4.8.0 #3138

Closed FrogDevelopper closed 5 days ago

FrogDevelopper commented 1 week ago

Expected Behavior

With version 4.7.1, when returning a Page.empty() in HttpResponse, no error was raised

Actual Behaviour

With new change in 4.8.0 (commit 696cc25) a new check was added

    public long getTotalSize() {
        if (totalSize == null) {
            throw new IllegalStateException("Page does not contain total count. " +
                "It is likely that the Pageable needs to be modified to request this information.");
        }
        return totalSize;
    }

with Page.empty() backed up by

Page<?> EMPTY = new DefaultPage<>(Collections.emptyList(), Pageable.unpaged(), null);

=> the total size is set to null => it will raise an error when returned in an endpoint

13:46:55.898 [virtual-executor1] ERROR i.m.http.server.RouteExecutor - Unexpected error occurred: Page does not contain total count. It is likely that the Pageable needs to be modified to request this information. java.lang.IllegalStateException: Page does not contain total count. It is likely that the Pageable needs to be modified to request this information. at io.micronaut.data.model.DefaultPage.getTotalSize(DefaultPage.java:68)

while in version 4.7.1, the total size was set to 0 and no null check was done

Page<?> EMPTY = new DefaultPage<>(Collections.emptyList(), Pageable.unpaged(), 0);

Steps To Reproduce

  1. Create a simple project with micronaut version 4.4.3 (= micronaut-data:4.7.1)
  2. Create a simple endpoint

    
    @Controller(MyController.BASE_ENDPOINT)
    @ExecuteOn(BLOCKING)
    public class MyController {
    
    public static final String BASE_ENDPOINT = "/items";
    
    @Status(OK)
    @Get("/search")
    public HttpResponse<Page<MyItem>> searchCampaigns(Pageable pageable) {
        return ok(Page.empty());
    }
    
    @Serdeable
    public record MyItem(String field1, Integer field2) { }
    }

@MicronautTest class MyControllerTest {

@Inject
@Client(MyController.BASE_ENDPOINT)
private HttpClient client;

@Test
void should_getEmptyPageable_when_searchingWithNonMatchingCriteria() {
    // Given

    // When
    var response = client.toBlocking().exchange(HttpRequest.GET("/search"), Page.class);

    // Then
    assertThat(response.getStatus().getCode()).isEqualTo(OK.getCode());
    assertThat(response.getBody()).isPresent();
    assertThat(response.getBody().get()).isEmpty();
}

}


3. Run the test => it pass
4. Upgrade to micronaut 4.5.1 (micronaut-data:4.8.4)
5. Run the tests => it doesn't pass anymore with the error
> ERROR i.m.http.server.RouteExecutor - Unexpected error occurred: Page does not contain total count. It is likely that the Pageable needs to be modified to request this information.
java.lang.IllegalStateException: Page does not contain total count. It is likely that the Pageable needs to be modified to request this information.
    at io.micronaut.data.model.DefaultPage.getTotalSize(DefaultPage.java:68)

### Environment Information

JDK Version: 21

### Example Application

https://github.com/FrogDevelopper/micronaut-4_5

### Version

4.5.1
radovanradic commented 5 days ago

Fixed by https://github.com/micronaut-projects/micronaut-data/pull/3142