Shaun Abram
Technology and Leadership Blog
Persisting Money class with Hibernate
Further to my previous post about representing monetary amounts in Java, I have been using the TimeAndMoney library.
I ran into some problems persisting my classes that use Money via Hibernate. I should point out that these are not problems with the Money class or the timeandmoney library, rather than with my hibernate setup, but I thought I would post my approach here for future reference.
I started by incorrectly trying to map my Money field (in my case, called ‘openingBalance) as a property, viz:
<property name=”openingBalance” type=”com.domainlanguage.money.Money”>
Which resulted in the following error:
SEVERE: Data truncation: Data too long for column ‘openingBalance’ at row 1
Exception in thread “main” org.hibernate.exception.GenericJDBCException: could not insert…
Then I tried mapping it as a component, viz
<component name=”openingBalance” class=”com.domainlanguage.money.Money”>
<property name=”amount”/>
<property name=”currency”/>
</component>
But this resulted in the following error:
Initial SessionFactory creation failed.org.hibernate.PropertyNotFoundException: Could not find a setter for property amount in class com.domainlanguage.money.Money
Exception in thread “main” java.lang.ExceptionInInitializerError
This is because the Money class has no setAmount or setCurrency methods. The solution is to specify field access (as opposed to accessor method access), as in
<component name=”openingBalance” class=”com.domainlanguage.money.Money”>
<property access=”field” name=”amount”/>
<property access=”field” name=”currency”/>
</component>
Note that if you check the Money javadocs, it (correctly) says that the setters are not provided because they would break encapsulation They do however (and I quote, “begrudgingly”) provide alternative setters such as setForPersistentMapping_Amount, but I am not sure how to get Hibernate to use these, and in this case, I don’t think it is necessary or beneficial anyway.
Tags: Hibernate, money, timeandmoney
Representing Money in Java
I’ve been writing some code recently that required dealing with monetary values but, as hard as it is to believe, there still doesn’t seem to be a great solution for money in Java. I’ve known for a while that float and double should never be used for representing money, or indeed anywhere exact values are required (e.g. 1 – 0.9 may give you something like 0.09999999999999998). Using long or int gives exact answers but requires keeping track of the decimal point yourself, which is a pain. A common approach is to use BigDecimal, but that is not without its limitations either e.g. it is certainly clunkier to use than primitives, and slower, and the rules for rounding and presentation seem a little complex.
Another solution is to use timeandmoney. It is a little worrying that it is still pre-alpha (v0.5.1 at time of writing), but I am going to go with it in the absence of any better contenders.
Note that some of this is covered in Josh Bloch’s definitive book, Effective Java, that I posted about before, and there are some discussions about the issues here.
Tags: money, timeandmoney