Search before asking
Describe the bug
While upgrading to Jackson 3 / Spring Boot 4 I noticed that DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES is now true by default, it defaulted to false in Jackson 2.
I agree that it's a good default to fail on attempt to deserialize JSON with null to a primitive, as primitives cannot be null.
But why does it fail on absent values? If I leave out a property for a reference field (String, LocalDate etc.) Jackson will default this field to null as expected, so I'd expect it would default boolean to false , int to 0 etc. Isn't this an unnecessary discrepancy between Java reference types and Java primitive types? Why is absent JSON fields for Java reference types defaulted but primitive fails?
Version Information
3.0.4
Reproduction
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import org.junit.jupiter.api.Test;
import tools.jackson.core.JacksonException;
import tools.jackson.databind.json.JsonMapper;
class JacksonDeserializationTest {
private static final JsonMapper JSON_MAPPER = JsonMapper.builder()
.build();
record StringRecord(String foo, String bar) {
}
record PrimitiveRecord(int int1, int int2, boolean boolean1, boolean boolean2) {
}
@Test
void shouldDeserializeAbsentStrings() {
// Given
String json = """
{
"bar": "barValue"
}
""";
// When
StringRecord actual = JSON_MAPPER.readValue(json, StringRecord.class);
// Then
assertThat(actual)
.as("Expect absent 'foo' to have default values (null for references)")
.isEqualTo(new StringRecord(null, "barValue"));
}
@Test
void shouldDeserializeAbsentPrimitives() {
// Given
String json = """
{
"int2": 42,
"boolean1": true
}
""";
// When
PrimitiveRecord actual = JSON_MAPPER.readValue(json, PrimitiveRecord.class);
// Then
assertThat(actual)
.as("Expect absent int1 and boolean2 have default values (0 and false)")
.isEqualTo(new PrimitiveRecord(0, 42, true, false));
}
@Test
void shouldFailDeserializeNullPrimitives() {
// Given
String json = """
{
"int1": 111
"int2": 222,
"boolean1": true,
"boolean2": null
}
""";
// When
Throwable thrown = catchThrowable(() -> JSON_MAPPER.readValue(json, PrimitiveRecord.class));
// Then
assertThat(thrown)
.as("Expect mapping null to primitive fails")
.isInstanceOf(JacksonException.class);
}
}
Expected behavior
I'd expect shouldDeserializeAbsentPrimitives() to pass with Jackson 3 using default configuration as it does with Jackson 2 with default configuration.
Additional context
No response
Search before asking
Describe the bug
While upgrading to Jackson 3 / Spring Boot 4 I noticed that
DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVESis nowtrueby default, it defaulted tofalsein Jackson 2.I agree that it's a good default to fail on attempt to deserialize JSON with
nullto a primitive, as primitives cannot benull.But why does it fail on
absentvalues? If I leave out a property for a reference field (String,LocalDateetc.) Jackson will default this field tonullas expected, so I'd expect it would defaultbooleantofalse,intto0etc. Isn't this an unnecessary discrepancy between Java reference types and Java primitive types? Why is absent JSON fields for Java reference types defaulted but primitive fails?Version Information
3.0.4
Reproduction
Expected behavior
I'd expect
shouldDeserializeAbsentPrimitives()to pass with Jackson 3 using default configuration as it does with Jackson 2 with default configuration.Additional context
No response