Reputation: 143
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
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
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
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