Java 将货币值存储为双倍,但使用BigDecimal计算值
目前,我们的一些Hibernate实体使用double来存储货币金额,数据库将该值存储为数字(10,2)。这些货币双倍金额的计算始终使用大小数进行计算,然后将实体值设置为双倍 例如:Java 将货币值存储为双倍,但使用BigDecimal计算值,java,hibernate,double,bigdecimal,Java,Hibernate,Double,Bigdecimal,目前,我们的一些Hibernate实体使用double来存储货币金额,数据库将该值存储为数字(10,2)。这些货币双倍金额的计算始终使用大小数进行计算,然后将实体值设置为双倍 例如: Order order = new Order(); OrderLineItem line = new OrderLineItem(1.0, 450.00); BigDecimal orderValue = BigDecimal.valueOf(line.getQty())
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());
到目前为止,这一切都很好,但我想知道这是否有可能导致某种舍入错误
想法?只要您的信息管道的每一部分都使用
BigDecimal。valueOf
和BigDecimal(double)
是绝对不用的,那么valueOf
的隐式四舍五入可能会阻止最坏的结果。但是你真的知道JPA和/或JDBC是如何在numeric(10,2)
和double
之间转换的吗?你确定这在将来不会改变吗
另一点:valueOf
和doubleValue
使用中间String
表示。在某些情况下,这可能是性能和垃圾收集问题
除此之外,还有足够多的关于双精度问题的示例-只需查看右侧的“相关”部分即可。或者看看这里,即使是简单的东西也会造成巨大破坏
所以这种情况有点像超速行驶:有些人不这样做,有些人有时这样做,希望什么都不发生,有些人。。。我想你明白了。一路走更安全。。。从您所说的来看,它在数据库中已经是BigDecimal,在您的应用程序代码中已经是BigDecimal,那么为什么不更新实体定义呢?我正在考虑这一点,但是如果我们重构,因为我们还使用了投影查询,因此它期望值是Double而不是bigdecime,所以当我们从对象转换为Double时,它不会显示为编译错误。此外,由于我们目前没有针对整个应用程序的测试用例,这意味着需要进行大量的测试。通常在金融界,您将所有值以便士/美分的形式存储为长的。您不应该对货币使用浮点值,并且BigDecimal是不必要的。只需使用long
s即可。