spring data jpa limit pagesize, how to set to maxSize
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;
}
}
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:
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:
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.
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.
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);
}
}