16

I'm trying to implement a controller method similar to how is documented in the latest Gosling release train of Spring Data that supports QueryDsl. I've implemented the controller as shown in the example in the docs at http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#core.web.type-safe. Everything compiles and when I start the application (using Spring Boot 1.2.5.RELEASE), everything starts fine.

However, when I try to call my rest endpoint, I always get the following exception:

org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mysema.query.types.Predicate]: Specified class is an interface
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:80)

My guess is that the QuerydslPredicateArgumentResolver is not being applied to the request, and thus the exception. But I see that the QuerydslPredicateArgumentResolver is registered as a bean when I query the Spring Boot manage endpoint /manage/beans. I have also ensured that @EnableSpringDataWebSupport is on my @Configuration class to no effect.

I have the controller annotated with @BasePathAwareController, since I'm using this with Spring Data REST and I want the methods to be under a similar path as the ones that Spring Data REST exposes. I also tried using @RepositoryRestController, but that didn't seem to matter. However, when using @RestController and putting it under a path that was different then the base path that Spring Data REST is using, things worked. So the question is, should it work?

The entire controller right now is:

@RestController
@RequestMapping(value = "/query")
public class AvailController
{
    private final AvailRepository repo;

    @Autowired
    public AvailController(AvailRepository repository)
    {
        this.repo = repository;
    }

    @RequestMapping(value = "/avails", method = GET)
    public @ResponseBody Page<Avail> getAvails(Model model, 
               @QuerydslPredicate(root = Avail.class) Predicate predicate,
               Pageable pageable, 
               @RequestParam MultiValueMap<String, String> parameters)
    {
        return repo.findAll(predicate, pageable);
    }
}
鄭脈龍
  • 336
  • 1
  • 10
Marc Zampetti
  • 733
  • 7
  • 20
  • I got it working, but with XML config. Perhaps this might help https://stackoverflow.com/questions/32366562/how-do-i-configure-xml-querydsl-to-be-used-with-spring-data-and-spring-mvc – Neil McGuigan Sep 10 '15 at 20:42
  • Manual Web Mvc Configuration can also lead to similar errors. See https://stackoverflow.com/a/62835165/6346531 – aksh1618 Jul 10 '20 at 13:21

2 Answers2

1

I had the same problem with instantiation of Predicate. In the example:

@Controller
@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
class UserController {

private final UserRepository repository;

@RequestMapping(value = "/", method = RequestMethod.GET)
String index(Model model, //
        @QuerydslPredicate(root = User.class) Predicate predicate, //
        @PageableDefault(sort = { "lastname", "firstname" }) Pageable pageable, //
        @RequestParam MultiValueMap<String, String> parameters) {
(...)

(https://github.com/spring-projects/spring-data-examples/blob/master/web/querydsl/src/main/java/example/users/web/UserController.java#L42 ) is using just @Controller and I was using @RepositoryRestController, that seems to be the reason. @RestController also works for me.

I created https://jira.spring.io/browse/DATAREST-838

domgom
  • 283
  • 2
  • 9
-1

I also had this issue when trying to implement a custom controller that mimics the returned value as Spring Data REST. I wanted to inject QuerydslPredicate to the controller method and got the annoying 'BeanInstantiationException'.

I found a work around for this by adding the following configuration file to my application:

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE   )
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Autowired
    @Qualifier("repositoryExporterHandlerAdapter")
    RequestMappingHandlerAdapter repositoryExporterHandlerAdapter;

    @Override
    public void addArgumentResolvers(
            List<HandlerMethodArgumentResolver> argumentResolvers) {
        List<HandlerMethodArgumentResolver> customArgumentResolvers = repositoryExporterHandlerAdapter.getCustomArgumentResolvers();
        argumentResolvers.addAll(customArgumentResolvers);
    }
}

See here for reference: https://jira.spring.io/browse/DATAREST-657