迁移到Java 1.4到Java 1.5+时,避免BigDecimal出现问题 [英] Avoid the problem with BigDecimal when migrating to Java 1.4 to Java 1.5+

查看:108
本文介绍了迁移到Java 1.4到Java 1.5+时,避免BigDecimal出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've recently migrated a Java 1.4 application to a Java 6 environment. Unfortunately, I encountered a problem with the BigDecimal storage in a Oracle database. To summarize, when I try to store a "7.65E+7" BigDecimal value (76,500,000.00) in the database, Oracle stores in reality the value of 7,650,000.00. This defect is due to the rewritting of the BigDecimal class in Java 1.5 (see here).

在我的代码中,BigDecimal是使用以下代码从double创建的:

In my code, the BigDecimal was created from a double using this kind of code:

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

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

In more than 99% of the cases, everything works fine. Except that in really few case, the bug mentioned above occurs. And that's quite annoying.

如果我更改先前的代码以避免使用BigDecimal的String构造函数,那么在用例中我不会遇到错误 :

If I change the previous code to avoid the use of the String constructor of BigDecimal, then I do not encounter the bug in my uses cases:

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

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

However, how can I be sure that this solution is the correct way to handle the use of BigDecimal?

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

So my question is to know how I have to manage my BigDecimal values to avoid this issue:

  • 不使用new BigDecimal(String)构造函数而直接使用new BigDecimal(double)吗?
  • 强制Oracle在处理BigDecimal时使用toPlainString()而不是toString()方法(在这种情况下该怎么做)?
  • 还有其他解决方案吗?
  • Do not use the new BigDecimal(String) constructor and use directly the new BigDecimal(double)?
  • Force Oracle to use toPlainString() instead of toString() method when dealing with BigDecimal (and in this case how to do that)?
  • Any other solution?

环境信息:

  • 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.

Edit : I've tested the same code in error but with the Oracle JDBC version 10.2.0.4.0 and the bug did not occur! The value stored was indeed 76,500,000.00... Regarding the changelog, maybe it is related to the bug #4711863.

推荐答案

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

With modern Hibernate versions you can use UserType to map any class to a database field. Just make a custom UserType and use it to map BigDecimal object to database column.

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

这篇关于迁移到Java 1.4到Java 1.5+时,避免BigDecimal出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆