我最近将 Java 1.4 应用程序迁移到 Java 6 环境。不幸的是,我遇到了一个问题 BigDecimal 存储在Oracle数据库中。总而言之,当我尝试存储 "7.65E+7" 大十进制值 (76,500,000.00)在数据库中,Oracle 实际上存储了以下值 7,650,000.00. 。这个缺陷是由于重写了 BigDecimal Java 1.5 中的类(参见 这里).

在我的代码中, BigDecimal 是从一个创建的 double 使用这种代码:

BigDecimal myBD = new BigDecimal("" + someDoubleValue);
someObject.setAmount(myBD);
// Now let Hibernate persists my object in DB...

在超过 99% 的情况下,一切正常。除了极少数情况下,会发生上述错误。这很烦人。

如果我更改前面的代码以避免使用 String 构造函数 BigDecimal, ,那么我就没有遇到这个bug 在我的用例中:

BigDecimal myBD = new BigDecimal(someDoubleValue);
someObject.setAmount(myBD);
// Now let Hibernate persists my object in DB...

但是,我如何确定该解决方案是处理使用的正确方法 BigDecimal?

所以我的问题是知道我必须如何管理我的 BigDecimal 避免此问题的值:

  • 不要使用 new BigDecimal(String) 构造函数并直接使用 new BigDecimal(double)?
  • 强制 Oracle 使用 toPlainString() 代替 toString() 处理时的方法 BigDecimal (在这种情况下该怎么做)?
  • 还有其他解决方案吗?

环境信息:

  • Java 1.6.0_14
  • Hibernate 2.1.8(是的,这是一个相当旧的版本)
  • Oracle JDBC 9.0.2.0 并使用 10.2.0.3.0 进行了测试
  • Oracle数据库10.2.0.3.0

编辑 : 我已经使用 Oracle JDBC 版本 10.2.0 测试了相同的错误代码。4.0 并且该错误确实发生了 不是 发生!存储的值确实是 76,500,000.00...关于 变更日志, ,可能与错误#4711863有关。

有帮助吗?

解决方案

使用现代 Hibernate 版本,您可以使用 UserType 将任何类映射到数据库字段。只需创建一个自定义 UserType 并使用它将 BigDecimal 对象映射到数据库列。

http://i-proving.com/space/Technologies/Hibernate/User+Types+in+Hibernate

其他提示

忏悔:我个人不使用 Hibernate,但是您可以创建一个子类 MyBigDecimal,其 toString() 方法调用 toPlainString() 吗?

我也不完全确定将双精度数传递给 BigDecimal 的构造函数的优点——双精度数本质上是不准确的,除非该数字完全由 2 的幂相加组成(有范围限制)。BigDecimal 的全部目的是规避这些对 double 的限制。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top