jackson-databind
jackson-databind copied to clipboard
If `JacksonInject` is specified for field and deserialized by the Creator, the inject process will be executed twice.
Search before asking
- [X] I searched in the issues and found nothing similar.
Describe the bug
SSIA
Version Information
2.16.0
Reproduction
The following is a sample using InjectableValues
that is made to count up when findInjectableValue
is called.
Since it is deserialized only once, the first ID is expected, but it is actually the second ID.
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class JacksonInjectForFieldTest {
static class Dto {
@JacksonInject("uuid")
private final UUID uuid;
@JsonCreator
Dto(
// @JacksonInject("uuid")
@JsonProperty("uuid")
UUID uuid
) {
this.uuid = uuid;
}
}
List<UUID> ids = Arrays.asList(UUID.randomUUID(), UUID.randomUUID());
class MyInjectableValues extends InjectableValues.Std {
int count = 0; // count up if injected
@Override
public Object findInjectableValue(
Object valueId,
DeserializationContext ctxt,
BeanProperty forProperty,
Object beanInstance
) throws JsonMappingException {
if (valueId.equals("uuid")) {
return ids.get(count++);
} else {
return super.findInjectableValue(valueId, ctxt, forProperty, beanInstance);
}
}
}
@Test
void test() throws JsonProcessingException {
ObjectReader reader = new ObjectMapper()
.readerFor(Dto.class)
.with(new MyInjectableValues());
Dto dto = reader.readValue("{}");
UUID actual = dto.uuid;
System.out.println(ids);
System.out.println(ids.get(0) == actual);
System.out.println(ids.get(1) == actual);
assertEquals(ids.get(0), actual);
}
}
Expected behavior
The inject process is executed only once. In fact, if a specification is made for a parameter, the result is as expected.
Additional context
After processing in the creator, another injection is performed on the field, so it is called twice in total.
I commented but forgot to mention the above initially. https://github.com/FasterXML/jackson-databind/issues/4218#issuecomment-1826461447