I'm updating my Spring Boot project to version 3.0.0 of Spring Boot. One important dependecy is the Spring Data Elastic Repository. I included the starter dependency:
implementation("org.springframework.boot:spring-boot-starter-data-elasticsearch")
After updating the dependecies, my unit test are failing, because no more null values are provided by the web controller. I tried to change the behavior by using the property inclusion configuration:
spring:
jackson:
default-property-inclusion: always
This did not help. I debugged the code party and it seems like the new Elastic Java Client has it's own Jackson Mapper config, which sets the global config to 'NON_NULL'.
package co.elastic.clients.json.jackson;
...
public class JacksonJsonpMapper extends JsonpMapperBase {
private final JacksonJsonProvider provider;
private final ObjectMapper objectMapper;
...
public JacksonJsonpMapper(ObjectMapper objectMapper) {
this(
objectMapper
.configure(SerializationFeature.INDENT_OUTPUT, false)
.setSerializationInclusion(JsonInclude.Include.NON_NULL),
// Creating the json factory from the mapper ensures it will be returned by JsonParser.getCodec()
new JacksonJsonProvider(objectMapper.getFactory())
);
}
...
Does anybody know how to solve this issue?
CodePudding user response:
I found a soultion for the problem. Spring Boot has an autoconfiguration for the Elastic Jackson mapper. This autocofiguration uses the same ObjectMapper as the web controller:
´´´
package org.springframework.boot.autoconfigure.elasticsearch;
...
/**
* Configurations for import into {@link ElasticsearchClientAutoConfiguration}.
*
* @author Andy Wilkinson
*/
class ElasticsearchClientConfigurations {
@ConditionalOnMissingBean(JsonpMapper.class)
@ConditionalOnBean(ObjectMapper.class)
@Configuration(proxyBeanMethods = false)
static class JacksonJsonpMapperConfiguration {
@Bean
JacksonJsonpMapper jacksonJsonpMapper(ObjectMapper objectMapper) {
return new JacksonJsonpMapper(objectMapper);
}
}
...
´´´
It is possible to override this Bean to copy the ObjectMapper instance and create an own ObjectMapper for the Elastic client:
´´´
@Configuration
internal class CustomJacksonJsonpMapperConfiguration {
@Bean
fun jacksonJsonpMapper(objectMapper: ObjectMapper): JacksonJsonpMapper {
return JacksonJsonpMapper(objectMapper.copy())
}
}
´´´