0

I have the following code:

@Qualifier("dateObjectMapper")
private ObjectMapper mapper;

@Autowired
DefaultProjectTweetSearchProvider(
        Client client,
        ObjectMapper mapper) {
    this.client = client;
    this.mapper = mapper;
}

The above code is not working. I get an error message stating that the spring container cannot decide which bean to use in the constructor for ObjectMapper. If I instead place @Resource(name = "dateObjectMapper") above my mapper field, it works. Why is it working in that case? I have 2 ObjectMapper beans like so:

@Bean
ObjectMapper dateObjectMapper() {
   // ... 
}

@Bean
@Primary
ObjectMapper defaultObjectMapper() {
   // ... 
}
njk2015
  • 543
  • 9
  • 20
  • Add `@Qualifier("dateObjectMapper")` to method `dateObjectMapper()`. – Andreas Jun 09 '17 at 13:59
  • So you have to annotate **both** the Bean name (method) and the field where that bean is referenced? – njk2015 Jun 09 '17 at 14:01
  • No, not a duplicate. I have `@Autowired` on my constructor, not on my field. I don't need to put `@Autowired` above my field. – njk2015 Jun 09 '17 at 14:03
  • That is what the documentation says: [7.9.4 Fine-tuning annotation-based autowiring with qualifiers](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers). But as it says: *For a fallback match, the bean name is considered a default qualifier value.* – Andreas Jun 09 '17 at 14:03
  • Well actually, you *should* use `@Qualifier` both where bean is *defined* (`@Bean`) and where bean in *injected* (`@Autowired`). But, you're not actually using `@Qualifier` where the bean is injected, because that would be the constructor, which means that you should put the `@Qualifier` on the constructor *parameter*. – Andreas Jun 09 '17 at 14:06
  • I fixed it. I didn't have to use `@Qualifier` in both places. Instead, I simply place the `@Qualifier` annotation before the `ObjectMapper` parameter in the constructor and remove it from the field. Link was good for showing an example. Thanks! – njk2015 Jun 09 '17 at 14:10

1 Answers1

1

When you use constructor injection the @Qualifier annotation has to be on the argument.

private ObjectMapper mapper;

@Autowired
DefaultProjectTweetSearchProvider(
        Client client,
        @Qualifier("dateObjectMapper") ObjectMapper mapper) {
    this.client = client;
    this.mapper = mapper;
}

Be aware of the bean names. Your example:

@Bean
ObjectMapper dateObjectMapper() {
   // ... 
}

@Bean
@Primary
ObjectMapper defaultObjectMapper() {
   // ... 
}

Will create beans with the same names as the @Bean methods: dateObjectMapper and defaultObjectMapper.

Evgeni Dimitrov
  • 21,976
  • 33
  • 120
  • 145