Reputation: 11916
We're developing a stock trading application and debating whether we should introduce a data type for currency.
The proposed Currency
data type contains an amount and a type of currency(e.g. USD, EUR, JPY).
I'm against it at this point because we'd use it for a property type of persistent beans as well.
First, it'd contain redudant data. Take a StockQuote
class for example that contains OHLC(open, high, low, and close prices) of a given stock. If each of them were to be represented by a Currency
instance, then all of OHLC would have references to the same currency type(e.g USD). In financial applications, currency values are used all over the place, not just stock quotes, so we're talking about lots of redundancy.
Second, a Currency
instance is a combination of two values(amount and type of currency), so you'd either drop the type of currency altogether and store only the amount field in the database table or create a currency type column in the table for each Currency
property, which would be redundant within the table and break the 2nd normal form. Either way, reading a record from the table back into a StockQuote
object would be impossible with JPA and tricky at best with Hibernate.
Anyone faced similar problems before? Is it normal for financial applications to have a custom currency class? If so, how did you implement it with JPA/Hibernate?
Upvotes: 2
Views: 3259
Reputation: 533730
It is worth noting that stocks are not always quoted in plain currencies. e.g. Stocks on the LSE are quoted in pence, not pounds. All stocks on an exchange will be quotes in the same currency units so you can assume that for a given stock on a given exchange, you know what the currency is, making the currency redundant. All you need is the price.
Upvotes: 1
Reputation: 8287
The Currency entity models the world correctly, there is no going around it.
Your argument about StockQuote is not really a strong one, you can easily reduce it to 1 times currency type and 4 times a long integer.
Update:
@Entity
public StockQuote {
private java.util.Currency currency; // find a nice database mapping of this, or use a ISO 4217 String instead
private long open;
private long close;
private long high;
private long low;
}
seems to be sufficient for a good database mapping. Of course, if you make utility methods like
MyCurrencyAmount currency = StockQuote.getOpenAsMyCurrencyAmount();
then most of any overhead would be solved. But note that you need both the java.util.Currency (being without an amount) and your own CurrencyAmount (or whatever), being with the java.util.Currency and an amount.
Upvotes: 1
Reputation: 674
The 2nd normal form is not a "holy grail".
Sometimes it's better to break it. You are working with a finance application. It's important to have the same pricing to work with. If all data in your database has the same currency, then yes, it is not needed.
But if you use different currencies, then you must store the type of currency for each money value. You can't avoid it. If you do, then you could end up calculating with USD, while the original value was with currency BP or EUR. That will give very different values.
By the way: Java has it's own class: java.util.Currency
Upvotes: 0