Anton Raskin
Anton Raskin

Reputation: 143

morphia BigDecimal persistence issue

I'm using morphia to persist object that one of its fields is BigDecimal.

@Entity
class MyObject {
    BigDecimal myField;
}

And I try to save it to db:

    Morphia morphia = new Morphia();
    Datastore datastore = morphia.createDatastore(new MongoClient("localhost"), "myStore");
    morphia.getMapper().getConverters().addConverter(new BigDecimalConverter());
    MyObject foo = new MyObject ();
    foo.setMyField(new BigDecimal("1.1111111111111111"));
    datastore.save(foo);

But I get the following exception:

    Caused by: java.lang.RuntimeException: java.lang.NumberFormatException: Conversion to Decimal128 would require inexact rounding of 1.111111111111111160454356650006957352161407470703125
at org.mongodb.morphia.mapping.ValueMapper.toDBObject(ValueMapper.java:29)
at org.mongodb.morphia.mapping.Mapper.writeMappedField(Mapper.java:867)
at org.mongodb.morphia.mapping.Mapper.toDBObject(Mapper.java:982)
... 7 more

Upvotes: 1

Views: 1431

Answers (3)

sajitha_ds
sajitha_ds

Reputation: 1

To my knowledge Morphia does not fully support big decimals, but this dependency converts Big decimals to a datatype that it supports.

https://mvnrepository.com/artifact/dev.morphia.morphia/core/1.5.8

Upvotes: 0

Nic Cottrell
Nic Cottrell

Reputation: 9665

Note also that some people have had problems with BigDecimal and older versions of the java driver. (See this issue). Make sure you have mongo-java-driver version 3.5.0 or newer.

Upvotes: 0

Shai Givati
Shai Givati

Reputation: 1156

As you mentioned, the Morphia package does have its own BigDecimalConverter that you can register to the object. But if you need some other custom behavior, you can create a converter of your own. For example, when I needed to change the BigDecimalConverter's encode implementation, I extended this class with one that overrode this method. Check out the following implementation.

public class CustomBigDecimalConverter extends 
org.mongodb.morphia.converters.BigDecimalConverter {

    public CustomBigDecimalConverter() {
        super();
    }

    @Override
    public Object encode(final Object value, final MappedField optionalExtraInfo) {
        if (value instanceof BigDecimal) {
            return ((BigDecimal) value).setScale(10, RoundingMode.CEILING);
        }
        return super.encode(value, optionalExtraInfo);
    }
} 

Upvotes: 1

Related Questions