2
votes

I'm trying to use the QuerydslBinderCustomizer to perform the usage of @QuerydslPredicate in my Rest controller.

I'm using a @Repositoy implementation to perform customized queries and joins with another tables representing the access level for the query.

Following the documentation

Current Spring JPA version that contains QuerydslBinderCustomizer: spring-data-commons-2.0.7.RELEASE.jar

The problem:

I'm trying to apply a like() operation in the serviceExecution.code field, but I only receive the predicate based on eq() and the customize method is not called at all.

I also try to put the code inside a interface based Repository, without success.

The Repository implementation is this one:

@Repository 
public class ServiceExecutionQueryRepositoryImpl extends JpaQuerydslBaseRepository<Long, ServiceExecution> implements ServiceExecutionQueryRepository, QuerydslBinderCustomizer<QServiceExecution>, QuerydslPredicateExecutor<ServiceExecution> {

    @Override
    public void customize(QuerydslBindings bindings, QServiceExecution serviceExecution) {

        bindings.bind(serviceExecution.code).first((path, value) -> path.likeIgnoreCase(StringUtils.like(value)));
        // breakpoint never hit this method.
        // bindings is not applied to the query
        ... another bindings

    }
}

The Resource method call:

    @GetMapping("/service-executions")
    public ResponseEntity<Page<ServiceExecutionDTO>> getAllServiceExecutions(
        @RequestParam(required = false) MultiValueMap<String, String> parameters,
        @QuerydslPredicate(root = ServiceExecution.class) Predicate predicate, Pageable pageable) {
        Page<ServiceExecutionDTO> page = facade.findAll(parameters, predicate, pageable);
        return new ResponseEntity<>(page, HttpStatus.OK);
    }

The resulting query generated (seen in application logs) is always this one (including count query):

select o from ... where code = ?

Can anyone know what I'm possible missing? Is something related to the recent Spring Data JPA version?

Details:

It's a gradle using project for Spring Boot, apt is configured. Except this issue, Querydsl is currently working as expected.

It's possible OK to check the Predicates on each method and transform to a like (I don't know if / know it's possible), but even being possible it doesn't sounds like a good workaround.

Docs: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web.binding

One of tutorials that I have followed: https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling

Similar question: Spring @QuerydslPredicate Questions

QueryDsl web query on the key of a Map field (Invalid because it uses a previous version of spring) EDIT

It seems that QuerydslBindingsFactory is loading only interfaces for bindings.

I'm using a interface with @NoRepositoryBean, that is not listed in the map that search for custom bindings. Maybe this the cause for the QuerydslBinderCustomizer not being called and added to the application bindings.

Anyway, I still don't know how to fix that.

1

1 Answers

1
votes

It seems you just forgot to add your ServiceExecutionQueryRepositoryImpl as bindings parameter of @QuerydslPredicate annotation:

@GetMapping("/service-executions")
public ResponseEntity<Page<ServiceExecutionDTO>> getAllServiceExecutions(
    @RequestParam(required = false) MultiValueMap<String, String> parameters,
    @QuerydslPredicate(root = ServiceExecution.class, bindings = ServiceExecutionQueryRepositoryImpl.class) Predicate predicate, 
    Pageable pageable
) {
    Page<ServiceExecutionDTO> page = facade.findAll(parameters, predicate, pageable);
    return new ResponseEntity<>(page, HttpStatus.OK);
}

See may example: sb-querydsl-sd-demo