Skip to content

BigDecimal values via @JsonTypeInfo/@JsonSubTypes get rounded #965

@gmjabs

Description

@gmjabs

When using an ObjectMapper to serialize/deserialize a class with an Object field annotated with a @JsonSubTypes.Type that indicate BigDecimal, it looks like the value is getting rounded to a double.

I tried configuring DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, but that didn't seem to help.

What I think is a valid repro is below, but let me know if I'm actually doing something wrong here.

Thanks!

import org.junit.Test;
import org.junit.Assert;

import java.math.BigDecimal;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTest {

    enum Type { BIG_DECIMAL }

    static class Wrapper {

        @JsonIgnore
        Type typeEnum;

        @JsonIgnore
        Object value;

        Wrapper() { }

        @JsonGetter(value = "type")
        String getTypeString() {
            return typeEnum.name();
        }

        @JsonSetter(value = "type")
        void setTypeString(String type) {
            this.typeEnum = Type.valueOf(type);
        }

        @JsonGetter(value = "objectValue") 
        Object getValue() {
            return value;
        }

        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
        @JsonSubTypes({ @JsonSubTypes.Type(name = "BIG_DECIMAL", value = BigDecimal.class) })
        @JsonSetter(value = "objectValue") 
        private void setValue(Object value) {
            this.value = value;
        }
    }

    @Test
    public void test() throws Exception {

        ObjectMapper m = new ObjectMapper();
        m.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);

        Wrapper w = new Wrapper();
        w.typeEnum = Type.BIG_DECIMAL;
        w.value = new BigDecimal("-10000000000.0000000001");

        String json = m.writeValueAsString(w);
        Wrapper w2 = m.readValue(json, Wrapper.class);

        Assert.assertEquals(w.typeEnum, w2.typeEnum);
        Assert.assertTrue(String.format("Expected %s = %s; got back %s = %s",
            w.value.getClass().getSimpleName(), w.value.toString(), w2.value.getClass().getSimpleName(), w2.value.toString()),
            w.value.equals(w2.value));
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions