Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception using Spring Data JPA and QueryDsl via REST Controller

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);
    }
}
like image 734
Marc Zampetti Avatar asked Sep 09 '15 18:09

Marc Zampetti


People also ask

What is Querydsl spring boot?

Querydsl is a framework that enables the construction of statically typed SQL-like queries through its fluent API. Spring Data modules offer integration with Querydsl through QuerydslPredicateExecutor .

What is Querydsl JPA?

Querydsl is an extensive Java framework, which allows for the generation of type-safe queries in a syntax similar to SQL. It currently has a wide range of support for various backends through the use of separate modules including JPA, JDO, SQL, Java collections, RDF, Lucene, Hibernate Search, and MongoDB.

What is @PageableDefault?

Annotation Type PageableDefault. @Documented @Retention(value=RUNTIME) @Target(value=PARAMETER) public @interface PageableDefault. Annotation to set defaults when injecting a Pageable into a controller method. Instead of configuring sort() and direction() you can also use SortDefault or SortDefault.

What is predicate in Querydsl?

Predicate is the common interface for Boolean typed expressions.


1 Answers

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

like image 198
domgom Avatar answered Oct 10 '22 04:10

domgom