anunaki
anunaki

Reputation: 2254

Spring boot two object mapper bean

I want to create two Hibernate aware object mapper bean in my Spring boot project.

One bean to force lazy loading and another to force lazy loading set as false. My bean definition as below :

I created a HibernateAwareObjectMapper class

public class HibernateAwareObjectMapper extends ObjectMapper {
}

and

@Configuration
public class CrewuiserCorebeans extends WebMvcConfigurerAdapter {

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Bean
public ObjectMapper defaultObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    Hibernate5Module hibernate5Module = new Hibernate5Module();
    hibernate5Module.configure(Hibernate5Module.Feature.FORCE_LAZY_LOADING, true);
    objectMapper.registerModule(hibernate5Module);
    return objectMapper;
}

@Bean
public HibernateAwareObjectMapper hibernateAwareObjectMapper() {
    HibernateAwareObjectMapper objectMapper = new HibernateAwareObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    Hibernate5Module hibernate5Module = new Hibernate5Module();
    hibernate5Module.configure(Hibernate5Module.Feature.FORCE_LAZY_LOADING, false);
    objectMapper.registerModule(hibernate5Module);
    return objectMapper;
}


@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    argumentResolvers.add(new UserContextResolver());
}

}

When I run the application, I am getting below error:

Parameter 0 of method mappingJackson2HttpMessageConverter in org.springframework.boot.autoconfigure.web.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration required a single bean, but 2 were found:
- defaultObjectMapper: defined by method 'defaultObjectMapper' in class path resource [com/crewuiser/core/configuration/CrewuiserCorebeans.class]
- hibernateAwareObjectMapper: defined by method 'hibernateAwareObjectMapper' in class path resource [com/crewuiser/core/configuration/CrewuiserCorebeans.class]

org.springframework.boot.autoconfigure.web.JacksonHttpMessageConvertersConfiguration is in jar, so I can't add @Qualifier annotation.

Please help, if I am missing anything here.How I can make it work?

Upvotes: 6

Views: 7847

Answers (3)

Alexander Taylor
Alexander Taylor

Reputation: 17642

Another way to use different parameters / configuration in different situations is to create an ObjectReader from the ObjectMapper, with customizations that override the ObjectMapper configuration. For example, objectMapper.readerFor(YourClass.class).with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)

Got this idea from here: https://stackoverflow.com/a/58294093/345648

This isn't necessarily the best way, depending on your use case. Check out anunaki's answer too.

Upvotes: 0

Vaibhav Kharche
Vaibhav Kharche

Reputation: 1

You can give name to the bean as below:

@Bean("bean1")
public ObjectMapper defaultObjectMapper() {
.......
}

@Bean("bean2")
public HibernateAwareObjectMapper hibernateAwareObjectMapper() {
.....    
}

and where you want to autowire it use @Qualifier("bean1") for bean1 or @Qualifier("bean2") for bean2.

Upvotes: -2

anunaki
anunaki

Reputation: 2254

I found a solution.

I added @Primary to one of the bean and used @Qualifier in my other classes where non-primary bean need to @Autowired.

@Bean
@Primary
public ObjectMapper defaultObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    return objectMapper;
}

and in my service class.

@Autowired
public OrganisationService(OrganisationValidator organisationValidator, OrganisationAuthority organisationAuthority,
                           OrganisationHelper organisationHelper, OrganisationRepository organisationRepository,
                           @Qualifier("hibernateAwareObjectMapper") ObjectMapper hibernateAwareObjectMapper) {}

Upvotes: 11

Related Questions