0

I'm using Query by Example to implement a number of complex filters in my Spring Boot application.

I use an ExampleMatcher to define how the String properties must be handled. So I have a code similar to the one bellow in several different controllers that need the filter:

  @GetMapping("/municipio/filter")
  public @ResponseBody ResponseEntity<?> filtro(
    Municipio municipio,
    Pageable page,
    PagedResourcesAssembler<Municipio> assembler
  ){

    ExampleMatcher matcher = ExampleMatcher.matching()
        .withIgnoreCase()
        .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);

    Example example = Example.of(municipio, matcher);
    Page<Municipio> municipios = this.municipioRepository.findAll(example, page);
    return ResponseEntity.ok(assembler.toResource(municipios));

  }

I would like to define the ExampleMatcher in a centralized way, to avoid replicating this configuration in every controller. So I tried to define it as a Bean and inject it this way:

@Configuration
public class AppConfig {

  @Bean
  public ExampleMatcher getExampleMatcher() {
    return ExampleMatcher.matching()
        .withIgnoreCase()
        .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);
  }
}

//Withing the controller class
@GetMapping("/municipio/filter")
public @ResponseBody ResponseEntity<?> filtro(
    Municipio municipio,
    Pageable page,
    PagedResourcesAssembler<Municipio> assembler,
    ExampleMatcher matcher //ExampleMatcher should be injected by Spring
  ){

    Example example = Example.of(municipio, matcher);
    Page<Municipio> municipios = this.municipioRepository.findAll(example, page);
    return ResponseEntity.ok(assembler.toResource(municipios));

  }

But I get the following error:

[No primary or default constructor found for interface org.springframework.data.domain.ExampleMatcher]: java.lang.IllegalStateException: No primary or default constructor found for interface org.springframework.data.domain.ExampleMatcher

Can anyone point what I'm missing here?

Jefferson Lima
  • 5,186
  • 2
  • 28
  • 28

1 Answers1

0

ExampleMatcher matcher will not be injected as an argument of your controller method, see below code of how it must be defined:

@Controller// or @RestController
public class SomeController {
    @Autowired
    ExampleMatcher matcher;
    // rest of the code ...
}

and remove it from list of args

Pianov
  • 1,533
  • 9
  • 16
  • Thanks for your answer, @Jack. I thought that it could be injected, as the other parameters are. Would you mind explaining why it doesn't work for `ExampleMatcher`? – Jefferson Lima Nov 21 '18 at 13:42
  • (1) RequestParamMethodArgumentResolver does all job to resolve arguments for your controller's method - https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.html and (2) this post might help you to understand more - https://stackoverflow.com/questions/6835615/how-to-do-spring-request-parameter-conversion – Pianov Nov 24 '18 at 02:57