General data-binding package for Jackson (2.x): works on streaming API (core) implementation(s)
Apache License 2.0
3.52k
stars
1.38k
forks
source link
The `KeyDeserializer` specified in the class with `@JsonDeserialize(keyUsing = ...)` is overwritten by the `KeyDeserializer` specified in the `ObjectMapper`. #4444
[X] I searched in the issues and found nothing similar.
Describe the bug
SSIA
Also, the attached Java reproduction code is directly adding KeyDeserializer to SimpleModule, but it seemed to be reproduced when using KeyDeserializers.
Version Information
Reproduced in the latest 2.17 branch(fe42cf7).
Also, 2.16.1 seems to have the same problem.
Reproduction
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class KeyDeserializerOverwritten {
@JsonDeserialize(keyUsing = ForClass.class)
static class MyKey {
private final String value;
MyKey(String value) {
this.value = value;
}
}
static class ForClass extends KeyDeserializer {
@Override
public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {
return new MyKey(key + "-class");
}
}
static class ForMapper extends KeyDeserializer {
@Override
public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException {
return new MyKey(key + "-mapper");
}
}
TypeReference<Map<MyKey, String>> typeRef = new TypeReference<>() {};
@Test
void notCustom() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Map<MyKey, String> result = mapper.readValue("{\"foo\":null}", typeRef);
// OK
assertEquals("foo-class", result.keySet().stream().findFirst().get().value);
}
@Test
void addKeyDeserializer() throws JsonProcessingException {
SimpleModule sm = new SimpleModule();
sm.addKeyDeserializer(MyKey.class, new ForMapper());
ObjectMapper mapper = new ObjectMapper().registerModule(sm);
Map<MyKey, String> result = mapper.readValue("{\"foo\":null}", typeRef);
// NG
assertEquals("foo-class", result.keySet().stream().findFirst().get().value);
}
}
Expected behavior
Like JsonDeserializer, the KeyDeserializer specified for the class must be used.
Search before asking
Describe the bug
SSIA
Also, the attached
Java
reproduction code is directly addingKeyDeserializer
toSimpleModule
, but it seemed to be reproduced when usingKeyDeserializers
.Version Information
Reproduced in the latest 2.17 branch(fe42cf7). Also, 2.16.1 seems to have the same problem.
Reproduction
Expected behavior
Like
JsonDeserializer
, theKeyDeserializer
specified for the class must be used.Additional context
This problem was discovered during prototyping to solve https://github.com/FasterXML/jackson-module-kotlin/issues/777. https://github.com/ProjectMapK/jackson-module-kogera/pull/224
I'm not sure if I should merge it into
kotlin-module
as it is, since the default content provided byKotlinModule
overrides any user customization.