spring data jpa limit pagesize, how to set to maxSize
Asked Answered
Z

14

26

I have one requirement is to search by pageable and non-pageable,

and in my Java code, I use spring data jpa Pageable class,

 Pageable pageable = new PageRequest(
                    queryForm.getPageNumber()- 1, queryForm.getPageSize(),Sort.Direction.ASC,"id");  
Page page = repository.fullTextSearch(queryForm.getText(), pageable);

And I don't want to change the return structure,

So when non-pageable situation (search all), how to set the pageSize value to MAX ?

Zaibatsu answered 20/5, 2014 at 4:46 Comment(0)
F
36

In conjunction with Spring MVC you can use PageableDefaults annotation with value = Integer.MAX_VALUE like

public String showUsers(Model model, 
  @PageableDefaults(pageNumber = 0, value = Integer.MAX_VALUE) Pageable pageable) { … }

see PageableDefaults annotation Javadoc.

In any other client code you can set second constructor parameter to Integer.MAX_VALUE:

new PageRequest(
    queryForm.getPageNumber()- 1, 
    queryForm.getPageSize() == null ? Integer.MAX_VALUE : queryForm.getPageSize(),
    Sort.Direction.ASC,"id"); 

see PageRequest constructor. I assume that queryForm.getPageSize() is a wrapper type not a primitive. Otherwise you get a zero if pageSize wasn't set by the user (intentionally for a "search all" request).

UPDATE:

Since Spring Data Commons 1.6 you should use PageableDefault instead of PageableDefaults

public String showUsers(Model model, 
    @PageableDefault(page= 2 ,value = Integer.MAX_VALUE)

See PageableDefault annotation Javadoc.

Fossorial answered 20/5, 2014 at 17:45 Comment(2)
Use PageableDefault instead of PageableDefaults. It has the same functionality, but PageDefaults is deprecated since Spring Data Commons 1.6 (docs.spring.io/spring-data/commons/docs/1.6.x/api/org/…)Holozoic
The page size has limit upper bound as the 'maxPageSize' property of the PageableHandlerMethodArgumentResolver. For this reason if the @PageagleDeafult annotation has a greater value than the 'maxPageSize' the argument resolver will change it to 'maxPageSize'. To run properly needs also configure the 'maxPageSize' to Integer.MAX_VALUEHabakkuk
B
26

If you use Spring MVC this may help you. According to comments below this answer is fully correct for Spring 4.x.x and maybe ealier, but for Spring 5.x.x you probably need another solution.

The first thing that you have to do is to use @PageableDefault annotation and set size to Integer.MAX_VALUE or any other value you want:

public SomeResponseObject getSomething(
    @PageableDefault(size = Integer.MAX_VALUE) Pageable page
) {
    return someService.getSomething(page);
}

But it is not enough when your size value is very big (bigger than 2000 in Spring Data Core/spring-data-commons 1.12.3), because size will be still limited by maxPageSize variable in PageableHandlerMethodArgumentResolver class which is set by default to 2000. This was mentioned by pdorgambide. You will get something like this:
Response with size limited to 2000 because of default maxPageSize
As you can see there is size=2000 instead of expected size=2147483647 (size=Integer.MAX_VALUE).
So the second step is to change mentioned maxPageSize. We can do it by overriding PageableHandlerMethodArgumentResolver. One of the ways to do it is to create a proper java configuration file in a proper package - if you use such kind of configuration in your project. You can do it also in xml config file if your project uses such. There is my solution (Java Spring Configuration File):

@Configuration
@EnableConfigurationProperties
public class PaginationConfiguration extends SpringDataWebConfiguration {

    @Bean
    public PageableHandlerMethodArgumentResolver pageableResolver() {
        PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver =
            new PageableHandlerMethodArgumentResolver(sortResolver());

        pageableHandlerMethodArgumentResolver.setMaxPageSize(Integer.MAX_VALUE);

        return pageableHandlerMethodArgumentResolver;
    }

}

Now everything works as expected:
Response with proper size equal to Integer.MAX_VALUE which is 2147483647

It is also worth to mention that in @PageableDefault annotation value is equivalent to size. In other words it is alias for size. It means that instead of size=Integer.MAX_VALUE you can write value=Integer.MAX_VALUE. What is more althought it makes no sense you can use both in the same time. If they are different only size is taken into consideration.

Brassy answered 22/6, 2017 at 17:34 Comment(2)
@OWADVL is it though? As of Spring 5 there is no default constructor for org.springframework.data.web.config.SpringDataWebConfigurationStaffan
@Staffan This answer does not include Spring 5 and I think it is obvious when you look at the answer date. This answer was posted on Jun 22 2017, OWADVL commented it on Jul 23 2017 and first stable version of Spring 5 was released on Sep 28, 2017. So both answer and OWADVL comment were made before first stable release of Spring 5 came out. Now you might find out how to make it work in Spring 5 and post another, better, more complete answer :)Brassy
M
7

Here is a working solution for Spring 5.x.x. You just need to add the default constructor. See the above example :

@Configuration
public class PaginationConfiguration extends SpringDataWebConfiguration {

    /**
     * @param context           must not be {@literal null}.
     * @param conversionService must not be {@literal null}.
     */
    public PaginationConfiguration(ApplicationContext context,
                                   @Qualifier("mvcConversionService") ObjectFactory<ConversionService> conversionService) {
        super(context, conversionService);
    }

    @Bean
    public PageableHandlerMethodArgumentResolver pageableResolver() {
        PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver =
                new PageableHandlerMethodArgumentResolver(sortResolver());

        pageableHandlerMethodArgumentResolver.setMaxPageSize(Integer.MAX_VALUE);

        return pageableHandlerMethodArgumentResolver;
    }

}
Mesitylene answered 5/7, 2019 at 13:29 Comment(0)
G
6

If you need per-controller limits like this:

@RequestMapping(path = "/users")
public ModelAndView users(@PageableLimits(maxSize = 10) Pageable pageable) {
    ...
}

@RequestMapping(path = "/comments")
public ModelAndView comments(@PageableLimits(maxSize = 100) Pageable pageable) {
    ...
}

It can be done with custom annotation:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface PageableLimits {
    int maxSize() default Integer.MAX_VALUE;

    int minSize() default 0;
}

And extended PageableHandlerMethodArgumentResolver configuration:

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver() {

            @Override
            public Pageable resolveArgument(MethodParameter methodParameter, @Nullable ModelAndViewContainer mavContainer,
                                            NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) {
                Pageable p = super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
                return getLimitsFromAnnotation(p, methodParameter);
            }

            private Pageable getLimitsFromAnnotation(Pageable p, MethodParameter methodParameter) {

                PageableLimits limits = methodParameter.getParameterAnnotation(PageableLimits.class);

                if (limits == null) return p;

                if (p.getPageSize() > limits.maxSize())
                    return PageRequest.of(p.getPageNumber(), limits.maxSize(), p.getSort());
                else if (p.getPageSize() < limits.minSize())
                    return PageRequest.of(p.getPageNumber(), limits.minSize(), p.getSort());

                return p;
            }
        };

        resolver.setMaxPageSize(Integer.MAX_VALUE);
        argumentResolvers.add(resolver);
        super.addArgumentResolvers(argumentResolvers);
    }
}
Gregoriagregorian answered 19/10, 2017 at 18:26 Comment(1)
The problem with Pageable p = super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory); doesn't take what consumer has sent in request, its taking Page request [number: 0, size 2000], is there any way if we can take what consumer is sending ?Making
B
4

In newer versions of spring-data (since v2.0), you can simply create a bean of org.springframework.data.web.config.PageableHandlerMethodArgumentResolverCustomizer and set PageableHandlerMethodArgumentResolver.setMaxPageSize.

@Configuration
public class WebMvcConfig {

    @Bean
    public PageableHandlerMethodArgumentResolverCustomizer paginationCustomizer() {
        return pageableResolver -> pageableResolver.setMaxPageSize(5);
    }
}
Bowlds answered 12/9, 2020 at 23:50 Comment(0)
T
3

This could be a measure of security, so it can be done globally.

If you are using a Pageable in a @RestController then you can change the maximum with the property:

spring.data.web.pageable.max-page-size=1000000000 # 1 billion

If you are using a Pageable in a @RepositoryRestResource then you can change the maximum with the property:

spring.data.rest.max-page-size=1000000000 # 1 billion

Source https://medium.com/@rafiek/spring-data-pageable-maximum-page-size-1bcc9f5348aa

Tusker answered 24/12, 2022 at 15:17 Comment(0)
K
2

As of Spring Data 2.0 you can also do the following:

@Configuration
public class WebConfiguration implements PageableHandlerMethodArgumentResolverCustomizer {

    @Override
    public void customize(PageableHandlerMethodArgumentResolver pageableResolver) {
        pageableResolver.setFallbackPageable(Pageable.unpaged());
    }

}
Kettie answered 16/1, 2020 at 19:44 Comment(0)
V
0

This works for me:

All pageable request use MyCustomPage and use a default page and size if not found in request.

If size (number of record exceed the max value) i set a default value, which in this case 50.

public class MyCustomPage extends PageRequest{
    Integer MAX_PAGE_SIZE = 50
    //constructor 
    public MyCustomPage(Integer page, Integer size) {
        super(page,(size>MAX_PAGE_SIZE)?MAX_PAGE_SIZE:size);
    }
}
Voracious answered 7/6, 2017 at 10:11 Comment(0)
S
0

Maybe you could use:

@Override
@GetMapping("/some")
public ResponseEntity<Page<BaseEntityInformationDTO>> getTemplateInfo(
              @PageableDefault(sort = "displayedName") Pageable pageable, 
              @RequestParam(defaultValue = Integer.MAX_VALUE + "") Integer trueSize) {
    pageable = new PageRequest(pageable.getPageNumber, Math.max(pageable.getPageSize, trueSize),..)
    ....
}
Scornful answered 2/8, 2018 at 8:24 Comment(0)
H
0

I use this in my code:

public Page<MyObject> retrieveData(@RequestBody CustomParameters query, Pageable pageable, Sort sort) {
    if (pageable == null) {
        return new PageImpl<>(repository.findAll(query.buildSpecification(), sort));
    }
    return repository.findAll(query.buildSpecification(), pageable);
}

This has a couple of advantages. If you use this in controllers you can always define a Pageable and a Sort arguments, if the request contains a "page" parameter, a Pageable will be created automatically (if there is a "sort" parameter it will be included in the pageable if it's not null or in the Sort argument if it is).

You can customize the sortResolver and pageableResolver in you configuration and then you have the same behaviour in all your controllers.

This way when you send the request you can specify if you want just a number of records (sendig a "page" parameter, and "size") or if you want them all (not sending those parameters), but you always get the same return structure.

Horseshit answered 22/8, 2018 at 11:12 Comment(0)
A
0

For Spring 5.x.x, set spring.data.rest.max-page-size=2147483647 in application.properties.

Alded answered 14/2, 2019 at 2:52 Comment(1)
There is a "delete" link, if you are looking for it. But editing your answer to contain garbage text is not acceptable.Phospholipide
G
0
spring.data.rest.max-page-size=1000

use this property in application.property and assign a higher value.

Giverin answered 2/7, 2019 at 16:52 Comment(1)
this only works if you are using spring-data-rest. If not, I have found spring.data.web.pageable.max-page-size to work.Cesarean
E
0

The calling application can send the maximum value of integer (something like Integer.MAX_VALUE) to the API directly in page size.

To give maximum value explicitly we can provide below value in size.

pageable = PageRequest.of(0, Integer.MAX_VALUE);

You can also provide one variable like isPageable in this case, when clients needs full data, they can provide this value to false & you can override the page size based on this flag.

// pageable is coming from function
if(!isPageable)
    pageable = PageRequest.of(0, Integer.MAX_VALUE, pageable.getSort());

PageRequest's package org.springframework.data.domain.PageRequest

Eupatrid answered 16/11, 2019 at 13:12 Comment(0)
F
0

Use pageSize maximum length is 10;

@Getter
@Setter
public class Paging {

    @Range(min = 1, max = 99999999)
    public int page;

    @Range(min = 10, max = 10)
    public int pageSize;

}

Because when we send page to JPA Pageable object, It has a validation like this;

public final class PageableUtils {
    private PageableUtils() {
        throw new IllegalStateException("Cannot instantiate a utility class!");
    }

    public static int getOffsetAsInteger(Pageable pageable) {
        if (pageable.getOffset() > 2147483647L) {
            throw new InvalidDataAccessApiUsageException("Page offset exceeds Integer.MAX_VALUE (2147483647)");
        } else {
            return Math.toIntExact(pageable.getOffset());
        }
    }
}
    ...
    public long getOffset() {
        return (long)this.pageNumber * (long)this.pageSize;
    }
    ...
Fireproofing answered 9/12, 2023 at 10:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.