简体   繁体   中英

No primary or default constructor found for interface org.springframework.data.domain.Pageable

I was trying to implement Pageable in my RestController and running into issues with this error message "No primary or default constructor found for interface org.springframework.data.domain.Pageable"

My Controller is

@GetMapping("/rest/category/all/page")
public Page<ItemCategory> getAllItemCategoryByPage(Pageable pageable){
    Page<ItemCategory> categories = itemCategoryService.getAllItemCategoriesByPageable(pageable);
    return categories;
}

What am I doing wrong here. It is a Spring Boot 2.0 Application. Thanks in advance!

The selected solution is a workaround. You can make Spring resolve the parameters automatically using this configuration :

import org.springframework.context.annotation.Configuration;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.data.web.config.EnableSpringDataWebSupport;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
@EnableSpringDataWebSupport
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add( new PageableHandlerMethodArgumentResolver());
    }
}

If you use Clément Poissonnier's solution , check if a configuration class do not override another one .

I had the same problem and the solution below could not fix it:

@Configuration
@EnableSpringDataWebSupport
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add( new PageableHandlerMethodArgumentResolver());
    }
}

I still had the message:

No primary or default constructor found for interface org.springframework.data.domain.Pageable

I then realized the project had a Swagger configuration class :

@Configuration
@EnableSwagger2
public class SwaggerConfiguration extends WebMvcConfigurationSupport {
    // Swagger configuration...
}

and that the above WebMvcConfig configuration was ignored .

The solution was to have only one configuration class:

@Configuration
@EnableSwagger2
public class WebMvcConfig extends WebMvcConfigurationSupport {
    // Swagger configuration...

    @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
            argumentResolvers.add( new PageableHandlerMethodArgumentResolver());
        }
    }
}

You might also no need @EnableSpringDataWebSupport as pointed by John Paul Moore's answer

I had the same problem with the WebFlux app. Spring Boot 2.4.0 misses the corresponding @EnableSpringDataWebSupport for the reactive apps but luckily provide working resolver implementation. You can enable it in the following way:

@Configuration
public class PageableWebFluxConfiguration implements WebFluxConfigurer {

    @Override
    public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
        configurer.addCustomResolver(new ReactivePageableHandlerMethodArgumentResolver());
    }

}

I would suggest refactoring you controller to

public List<ItemCategory> getAllItemCategoryByPage(@RequestParam("page") int pageIndex, 
                                                   @RequestParam("size") int pageSize){
     return itemCategoryService
                   .getAllItemCategoriesByPageable(PageRequest.of(pageIndex, pageSize)).getContent();
}

I think you are missing an annotation before Pageable (how are you sending that data from client?).

Just to add to the answers already given regarding enabling @EnableSpringDataWebSupport using the annotation. This should already be enabled with spring boot auto configuration. You may need to check your configuration, or is this auto configuration class being excluded using java config or in application properties.

   org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration

For Non Spring Boot Code:

I was dealing with some existing spring mvc code base without spring boot, there was already a RequestMappingHandlerAdapter bean registered in the xmls, so I had to do this

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        ...
        <property name="customArgumentResolvers">
            <list>
                <bean class="org.springframework.data.web.PageableHandlerMethodArgumentResolver">
                </bean>
            </list>
        </property>
    </bean>

You can configure your test as:

@BeforeEach
public void setup(){
  mockMvc = MockMvcBuilders.standaloneSetup(messageController)
    .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
    .build();
}

See explanation https://www.javafixing.com/2021/12/fixed-request-is-not-being-executed-in.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM