2011-08-26 60 views
2

目前我們的一些Hibernate的實體使用雙打存儲貨幣金額,數據庫存儲這個值作爲一個數字(10,2)。這些貨幣雙重金額的計算總是使用BigDecimals計算,然後將實體值設置爲double。存儲貨幣值雙打,但使用的BigDecimal計算值

例子:

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()); 

這一直很好,到目前爲止,但我不知道是否該有某種形式的舍入誤差的任何潛在風險。

想法?

+1

更安全去的BigDecimal一路......從你說的時候,就已經是BigDecimal的在數據庫中,並BigDecimal的在應用程序代碼,所以爲什麼不更新實體的定義是什麼? – Thilo

+0

我正在考慮這一點,但是有一個連鎖反應,如果我們重構,因爲我們還可以使用其因此期待值是一個雙對BigDecimal的投影查詢,所以它不會顯示爲一個編譯錯誤,因爲我們從Object強制加倍。另外,由於我們目前沒有整個應用程序的測試用例,這意味着相當多的測試。 – David

+1

通常在金融世界中,您將所有價值以便士/美分作爲「長」存儲。您絕對不應該使用浮點值來獲取金錢,並且BigDecimal是不必要的。只要使用'長'。 –

回答

2

只要每一件你的信息管道使用BigDecimal.valueOfBigDecimal(double)用於絕對無處那麼valueOf隱式舍入可能會阻止最壞的打算。但是,你真的知道JPA和/或JDBC numeric(10,2)double之間如何轉化?你確定,這在未來不會改變嗎?

另一點:valueOfdoubleValue使用中間String表示法。在某些情況下,這可能是性能和垃圾收集問題。

而且這也有足夠的例子與double問題 - 簡單地看向右側的「相關」部分。或者看看這個blog即使簡單的東西可以破壞浩劫。

所以情況有點像超速:有些不這樣做,有時候有些做出來,希望什麼都不會發生,有些......我覺得你得到它。