I'm starting to play with Realm.io in an Android app that I'm writing. In one of my data objects, I'm required to store a currency value. Previously I had stored the value internally as a BigDecimal value and then converted that too and from a double value when moving in and out of the database.
I have always been told that it is a bad idea to store currency values in a double because of the way that they are handled. Unfortunately, Realm.io doesn't support the storage and retrieval of BigDecimal objects.
Is the best solution to write my own currency class that extends RealmObject and keeps that as a member variable of by data object?
The Realm is an object and mobile database. It's a data-storage solution for mobile and web development. A simpler definition would be that the Realm is where your app's or website's data is stored and managed. One could say that the Realm mobile database is the perfect replacement for SQLite and Core Data.
Realm is built from scratch with C++ as its core can run directly on different devices. It stores data in a native object format whereby objects are represented in the database in a universal table-based format. This makes Realm database easy to use in different languages and platforms.
Realm Database is an offline-first mobile object database in which you can directly access and store live objects without an ORM.
Realm is a database that is built to target mobile applications for iOS and Android. It works better and faster than SQLite and CoreData for iOS applications. It's easier to use and requires less code to store and retrieve data. It is free to use for iOS and Android apps without any limits.
Emanuele from Realm here.
You are right, using floats or doubles for currency is a bad idea.
We don't support BigDecimal for now, and before we do we will have to see how that plays in relation to all other language bindings since we want realm files to be compatible across all the supported platforms.
Christian's idea is good, but I see the conversion to and from String to be a bit slow. If you don't need the arbitrary precision property of BigDecimal you could use long
and multiply/divide by the factor your required precision calls for. This would also save a lot of space in terms of the size of the Realm file since integer values are bit packed.
That could work, but would probably be suboptimal if do calculations on your current BigDecimal objects.
You could also use the @Ignore annotation to provide a wrapper method for your custom objects like this:
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 as you need to expose the *dbValue() methods, but it should work.
I would also suggest going to https://github.com/realm/realm-java/issues and make a feature request for this as BigDecimal is probably one of those java classes used by so many that it could warrant native Realm support, just like Date has.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With