FasterXML / FasterXML/jackson-modules-java8

`Optional<JsonNode>` deserialization from "absent" value does not work in the expected way

Abierto
#250 4 comentarios 2 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Java
Estrellas
425
Forks
124
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

Example:
```java
public record MyRecord(
Optional myField
) {
}
```

When deserialized from: `{}`
Expected:
`myField.isPresent() == false`
Actual:
`myField.isPresent() == true`

This is because `myField` gets set to an `Optional` of a `NullNode`

After spending some time looking into the source code of both the `jackson-databind` and the `jackson-datatype-jdk8` libraries, the problem seems to lie in the `OptionalDeserializer` (or higher).

During deserialization, when a property is missing, the `PropertyValueBuffer::_findMissing` method is called and in it, this piece of code is called:
https://github.com/FasterXML/jackson-databind/blob/0fe97e0d69b7d5362907b094d5b979bc2216dc4a/src/main/java/com/fasterxml/jackson/databind/deser/impl/PropertyValueBuffer.java#L203
```java
// Third: NullValueProvider? (22-Sep-2019, [databind#2458])
// 08-Aug-2021, tatu: consider [databind#3214]; not null but "absent" value...
Object absentValue = prop.getNullValueProvider().getAbsentValue(_context);
if (absentValue != null) {
return absentValue;
}
```

The `OptionalDeserializer` is not overriding its inherited `getAbsentValue` method to return `Optional.ofNullable(_valueDeserializer.getAbsentValue(ctxt));` (or similar).

Due to the lack of the overriding, the inherited `getAbsentValue` method actually calls `getNullValue` instead as can be seen here:
https://github.com/FasterXML/jackson-databind/blob/0fe97e0d69b7d5362907b094d5b979bc2216dc4a/src/main/java/com/fasterxml/jackson/databind/JsonDeserializer.java#L349
```java
@Override
public Object getAbsentValue(DeserializationContext ctxt) throws JsonMappingException {
return getNullValue(ctxt);
}
```

In the case of a `JsonNode`, the `JsonNodeDeserializer` is used. This deserializer overrides the `getNullValue` method to return a `NullNode`.

https://github.com/FasterXML/jackson-databind/blob/0fe97e0d69b7d5362907b094d5b979bc2216dc4a/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java#L73
```java
@Override
public JsonNode getNullValue(DeserializationContext ctxt) {
return ctxt.getNodeFactory().nullNode();
}
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.