bguerout/jongo

Recording of Decimal128 via Jongo

Closed this issue · 28 comments

I'm working with Jongo 1.4, which is supposed to take into account Decimal128 type. Thus, I would like to know why, when I'm trying to register a Decimal128 in a database, it appears like an Object and not like a NumberValue ?
Do you have any solution for me to force NumberValue ?
Thank you in advance for your answer.

No answer ?

Hello, can you provide a code snippet with the POJO your are trying to store ?

I'm trying to store this POJO with a Decimal128 attribute :

decimal128
But it appears like an Object in my database (with high, low, negative, nan, infinite and finite parameters) :

capture du 2018-07-03 09-32-19

However, what I would like is something like this :
vf

That I created in this way :
capture du 2018-07-03 09-37-51

Do you have any proposition ?

Do you need any other information ?

Ok so i suppose you need to configure ObjectMapper to handle Decimal128.
I'm going to make a test

Ok, thank's! Have you found anything yet ? What's the result ?

Hello,
I'm on this project only until July 20, do you think it will be ok ?

Hello! Do you have some news ?

Is there any chance of getting an answer ?

This is not a working example but you need to create a custom serializer/deserializer:

Mapper mapper = jacksonMapper()
.addSerializer(Decimal128.class, new JsonSerializer<Decimal128>() {
    @Override
    public void serialize(Decimal128 decimal, JsonGenerator jgen, SerializerProvider provider) throws IOException {
       //write value into the generator by using for example decimal.bigDecimalValue()
        jgen.writeNumber(...);
    }
})
.addDeserializer(Decimal128.class, new JsonDeserializer<Decimal128>() {
    @Override
    public Decimal128 deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        //read value from parser and create new instance of Decimal128
        return new Decimal128(...);
    }
})
.build();

Jongo jongo = new Jongo(getDatabase(), mapper);

...

Note that Decimal128 should be support natively by jongo

Here is a working example using BigDecimal (+de/serilization into string)

 @Test
    public void canHandleDecimal128() {

        Decimal decimal = new Decimal();
        decimal.total = Decimal128.parse("10");

        collection.save(decimal);

        Decimal result = this.collection.findOne(decimal._id).as(Decimal.class);
        assertThat(result.total).isEqualTo(new Decimal128(10));
    }

    private static class Decimal {
        ObjectId _id;
        @JsonSerialize(using = Decimal128JsonSerializer.class)
        @JsonDeserialize(using = Decimal128JsonDeserializer.class)
        Decimal128 total;
    }

    private static class Decimal128JsonDeserializer extends JsonDeserializer<Decimal128> {
        @Override
        public Decimal128 deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
            return new Decimal128(new BigDecimal(jp.getValueAsString()));
        }
    }

    private static class Decimal128JsonSerializer extends JsonSerializer<Decimal128> {

        @Override
        public void serialize(Decimal128 decimal, JsonGenerator jgen, SerializerProvider provider) throws IOException {
            jgen.writeString(decimal.bigDecimalValue().toString());
        }
    }

This test has been added into test suite: https://github.com/bguerout/jongo/blob/master/src/test/java/org/jongo/spike/QuestionsSpikeTest.java#L195

The trouble with this is that writeNumber(BigDecimal value) transforms my value into a double value, not Decimal128 value...

Have you checked with the second example ?

"Note that Decimal128 should be support natively by jongo", not by jongo but by mongo, isn't it ?

I saw your second example, but the trouble is that my Decimal128 values can't be registred like string in my database (I do statistics so I need numerical values)

I also tried with this :
According to MongoDB documentation :
mongodoc
(source : https://docs.mongodb.com/manual/reference/mongodb-extended-json/#numberdecimal)
However, Jongo does not recognize the property "$numberDecimal" so it doesn't work

Not sure if the following serializer can do the job

    private static class Decimal128JsonSerializer extends JsonSerializer<Decimal128> {

        @Override
        public void serialize(Decimal128 decimal, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeFieldName("$numberDecimal");
            jsonGenerator.writeString(decimal.bigDecimalValue().toString());
            jsonGenerator.writeEndObject();
        }
    }
``

I'm going to try to add Decimal128 support into Jongo

Sorry but i can't presently release a version. I've created pull request to handle Decimal128.
I'm not sure evertyhing is ok and more tests needs to be made but may be you can check the code and try to do the same in your project. #341

No plans to release version to support Decimal128 before 1.5.0?

@bguerout : as @creativearmenia has said : "no plans to release version to support Decimal128 before 1.5.0?"

Is it possible to build by myself an intermediate version ?

This would be very appreciable :D
An idea of the release date ?

I've deployed a SNAPSHOT version.
It should be great if you can validate that this version solved the issue.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
...
    <dependencies>
        <dependency>
            <groupId>org.jongo</groupId>
            <artifactId>jongo</artifactId>
            <version>1.4.1-SNAPSHOT</version>
        </dependency>
    </dependencies>


    <repositories>
        <repository>
            <id>sonatype-snapshots</id>
            <name>Sonatype Public</name>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
...
</project>

After testing in an environnement composed of :

  • Play Framework 1.5.1
  • Mongo 3.4.24

It works perfectly !

Conf add in play dependencies.yml

require:
    - play
    - ...
    - org.jongo -> jongo 1.4.1-SNAPSHOT
    - ...

repositories:
    - sonatype:
        type: iBiblio
        root: "https://oss.sonatype.org/service/local/repositories/snapshots/content/"
        contains:
            - org.jongo -> *

Result obtained and observed using Robo3T :

test_result_in_mongo

Please let me know when version 1.4.1 will be officially delivered.
Thank you in advance

1.4.1 has just been released

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
...
    <dependencies>
        <dependency>
            <groupId>org.jongo</groupId>
            <artifactId>jongo</artifactId>
            <version>1.4.1</version>
        </dependency>
    </dependencies>
...
</project>

Thank you for everything