Using Realm.io to Store Money Values

I start playing with Realm.io in the Android application that I am writing. In one of my data objects I have to store the currency value. Previously, I stored this value internally as a BigDecimal value, and then converted it also from a double value when I entered and exited the database.

I have always been told that storing currency values ​​in double code is a bad idea because of the way they are processed. Unfortunately, Realm.io does not support storing and retrieving BigDecimal objects.

Is the best solution for writing my own currency class that extends RealmObject and saves it as a member variable of a data object?

+6
source share
4 answers

Emanuele of the Kingdom is here.

You're right, using float or double for currency is a bad idea.

We do not support BigDecimal at the moment, and before we do this, we will need to see how this happens with respect to all other language bindings, since we want realm files to be compatible on all supported platforms.

The Christian idea is good, but I see that converting to and from String is a bit slow. If you do not need the BigDecimal arbitrary precision property, you can use long and multiply / divide by a factor that is required for your desired precision. It will also save a lot of space on the size of the Realm file, since integer values ​​will be packed in bits.

+6
source

This might work, but probably would not be optimal if you were to do calculations for your current BigDecimal objects.

You can also use the @Ignore annotation to provide a wrapper method for your custom objects, for example:

 public class Money extends RealmObject { private String dbValue; @Ignore private BigDecimal value; public String getDbValue() { return dbValue; } public void setDbValue(String dbValue) { this.dbValue = dbValue; } public BigDecimal getValue() { return new BigDecimal(getDbValue()); } public void setValue(BigDecimal value) { setDbValue(value.toString()); } } 

It is not perfect, since you need to provide * dbValue () methods, but it should work.

I would also suggest going to https://github.com/realm/realm-java/issues and making a request for this function, since BigDecimal is probably one of those Java classes that are used by many, that it can guarantee support for native areas, like Date.

+5
source

What I do is keep it that way

I defined a constant in my application:

 public static final BigDecimal MONEY_PRECISION = new BigDecimal(1000); 

and when I need to save a large decimal number, it will look like this:

 public class MoneyClass extends RealmObject { long _price = 0; public void set_price(BigDecimal price) { this._price = price.longValue() * App.MONEY_PRECISION.longValue(); } public BigDecimal get_price() { return new BigDecimal(_price).divide(App.MONEY_PRECISION, 0, 0); } } 

In theory, this should be faster than storing it in lines, but I really didn’t look very well at the kingdom code

0
source

My decision:

Define Interface:

 public interface RealmConvert { void convertToDB(); void convertToObj(); } 

Define the entity:

 @Ignore private BigDecimal balance; private String balanceStr; 
 @Override public void convertToDB() { if (getBalance() != null) { setBalanceStr(getBalance().toString()); } } 
 @Override public void convertToObj() { if (getBalanceStr() != null) { setBalance(new BigDecimal(getBalanceStr())); } } 

Before copying ToRealm: calling the convertToDB method

When you need to use an entity: call the convert obj method

This is not an elegant solution, but it works.

Christian Cupronickel answer does not work in my application.

0
source

Source: https://habr.com/ru/post/1204147/