Skip to content

Trailing zeros are stripped when reading BigDecimal as JsonNode #3650

@TeppoLehtonen-TomTom

Description

@TeppoLehtonen-TomTom

Describe the bug
BigDecimal values are stripping trailing zeros from the JSON source when the concrete type is selected using a custom deserializer (@JsonDeserialize). This differs from the behavior of directly deserializing to the same concrete type, where the trailing zeroes are retained.

Version information
2.13.4.2

To Reproduce

import static org.junit.jupiter.api.Assertions.assertEquals;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.math.BigDecimal;
import org.junit.jupiter.api.Test;

class BigDecimalTrailingZeroesTest {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void bigDecimalTrailingZeroes() throws JsonProcessingException {
        // Passes
        assertEquals(
                new BigDecimal("5.00"),
                objectMapper.readValue("{\"value\": 5.00}", BigDecimalHolder.class).getValue());
    }

    @Test
    public void customDeserializedBigDecimalTrailingZeroes() throws JsonProcessingException {
        // org.opentest4j.AssertionFailedError:
        // Expected :5.00
        // Actual   :5.0
        assertEquals(
                new BigDecimal("5.00"),
                objectMapper.readValue("{\"value\": 5.00}", Holder.class).getValue());
    }

    @JsonDeserialize(as = BigDecimalHolder.class)
    private static class BigDecimalHolder implements Holder<BigDecimal> {
        private BigDecimal value;

        public BigDecimal getValue() {
            return value;
        }

        public void setValue(BigDecimal value) {
            this.value = value;
        }
    }

    @JsonDeserialize(using = HolderDeserializer.class)
    private interface Holder<T> {
        T getValue();
    }

    private static class HolderDeserializer extends JsonDeserializer<Holder<?>> {
        @Override
        public Holder<?> deserialize(JsonParser parser, DeserializationContext context)
                throws IOException {
            ObjectMapper mapper = (ObjectMapper) parser.getCodec();
            ObjectNode root = mapper.readTree(parser);
            return mapper.treeToValue(root, BigDecimalHolder.class);
        }
    }
}

Expected behavior
The same behavior in both cases, that the trailing zeroes are retained.

Additional context
This appears to be the very similar to the issue #2784.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions