2

I want to autowire a spring dependency into a jackson deserialization converter. E.g.,

 import com.fasterxml.jackson.databind.util.StdConverter;

 @Component
 public class LookupConverter extends StdConverter<T, T> {

    @Autowired
    private Repository<T> repo;

    @Override
    public IsoCountry convert(T value) {
        repo.findById(value.getId()).orElse(value);
    }
}

I have tried using: SpringBeanAutowiringSupport e.g.,

public LookupConverter() {
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}

but get the following message

Current WebApplicationContext is not available for processing of LookupConverter: Make sure this class gets constructed in a Spring web application. Proceeding without injection.

I have tried injecting a SpringHandlerInstantiator into the the ObjectMapper ala this and this

@Bean
public HandlerInstantiator handlerInstantiator(ApplicationContext applicationContext) {
    return new SpringHandlerInstantiator(applicationContext.getAutowireCapableBeanFactory());
}

@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder(HandlerInstantiator handlerInstantiator) {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.handlerInstantiator(handlerInstantiator);
    return builder;
}

This also does not work, seemingly because the SpringHandlerInstantiator is not being used and my custom Converter is not being instantiated by spring.

Any pointers to how this can be accomplished using Spring Boot 2.1.0 would be much appreciated.

undef
  • 425
  • 2
  • 8
  • Hmm. Could Spring possibly know what to inject if you've got your repository defined as generic? Do you have any qualifiers attached to the *explicit* repository you want to use? – Makoto Jan 14 '19 at 21:09
  • Yes, I tried with explicit `@Qualifier`s and it still doesn't work. The issue seems to be that The converters are not being managed by spring – undef Jan 15 '19 at 12:47
  • Did you manage to find a solution? I have a similar problem with custom deserializer and injecting SpringHandlerInstantiator doesn't work for me either. – Akisame Feb 08 '19 at 13:56
  • I ended up going with the static autowiring method which strikes me as a bit gross, but does work. E.g., `private static MyRepo repo` and an `@Autowired` setter – undef Feb 12 '19 at 11:20

1 Answers1

0

One way to get around this issue would be to create @Service that provides repository or repositories in a static way, for example:

@Service
public class RepositoryService {

    @Resource
    private ExampleEntityRepository repo;

    @Getter
    private static final Map<Class<?>, Repository<?, ?>> repos = new HashMap<>();

    @PostConstruct
    private void postConstruct() {
        repos.put(ExampleEntity.class, repo);
    }

}

Then instead of injecting repo to your converter you would do something like:

private Repository<ExampleEntity, Long> repo = RepositoryService.getRepos()
                                                       .get(ExampleEntity.class);
pirho
  • 11,565
  • 12
  • 43
  • 70
  • 2
    Thanks, I did try the static approach and it works but it feels too much like a hack for my liking – undef Jan 15 '19 at 12:48