2

Currently some of our Hibernate entities are using Doubles to store monetary amounts, the database stores this value as a numeric(10,2). The calculation of these monetary double amounts are always calculated using BigDecimals and then the entity value is set as a double.

Example:

Order order = new Order();
OrderLineItem line = new OrderLineItem(1.0, 450.00);
BigDecimal orderValue = BigDecimal.valueOf(line.getQty())
                        .multiply(BigDecimal.valueOf(line.getAmount()));
order.setOrderTotal(orderValue.setScale(2, ROUND_HALF_EVEN).doubleValue());

This has worked fine so far, however I'm wondering if this has any potential risks for some sort of rounding error.

Thoughts?

David
  • 657
  • 7
  • 18
  • 1
    much safer to go BigDecimal all the way... From what you say, it is already BigDecimal in the DB, and BigDecimal in your application code, so why not just update the entity definition? – Thilo Aug 26 '11 at 04:12
  • I am considering this, however there is a ripple effect if we refactor, as we also use projection queries which are therefore expecting the value to be a Double vs. BigDecimal so it will not show up as a compile error as we cast from Object to Double. Additionally, since we currently do not have a test case for the entire application it would mean quite a bit of testing. – David Aug 26 '11 at 04:25
  • 1
    Usually in the financial world you store all values in pennies / cents as a `long`. You should never use floating-point values for money, and BigDecimal is unnecessary. Just use `long`s. – Luigi Plinge Aug 26 '11 at 04:43

1 Answers1

2

As long as every piece of your information pipeline uses BigDecimal.valueOf and BigDecimal(double) is used absolutely nowhere then the implicit rounding of valueOf might prevent the worst. But do you really know how JPA and/or JDBC translate between numeric(10,2) and double? And are you sure, that this will not change in the future?

Another point: valueOf and doubleValue work with intermediate String representations. This might be a performance and garbage collection issue in some situations.

Besides of this there are enough examples for problems with double - simply look to the "Related" section on the right side. Or look at this blog where even simple stuff can wreck havoc.

So the situation is a little bit like speeding: Some don't do it, some do it sometimes and hope nothing happens and some... I think you get it.

A.H.
  • 57,703
  • 14
  • 82
  • 113