3

私は最近のJava 6環境へのJava 1.4のアプリケーションを移行しました。残念ながら、私は問題が発生しBigDecimal、Oracleデータベースに格納。私が保存しようとすると、要約すると"7.65E+7"BigDecimal値を(76,500,000.00実際には、データベース内)の値をOracleの店を7,650,000.00。この不具合はのrewrittingによるものである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バグは発生しません。

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

ただし、このソリューションがの使用を処理する正しい方法であることをどのように確認できますBigDecimalか?

だから私の質問は、私は私の管理しなければならない方法を知っているBigDecimalこの問題を回避するために、値を:

  • コンストラクターを使用せず、new BigDecimal(String)直接new BigDecimal(double)
  • 処理するときにメソッドtoPlainString()の代わりにOracleを使用するように強制しますか(この場合はその方法)?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

編集:同じコードを誤ってテストしましたが、OracleJDBCバージョン10.2.0を使用しました。4.0とバグは発生しませんでした!保存された値は確かに76,500,000.00...変更ログに関しては、バグ#4711863に関連している可能性があります。

4

2 に答える 2

3

最新のHibernateバージョンでは、UserTypeを使用して任意のクラスをデータベースフィールドにマップできます。カスタムUserTypeを作成し、それを使用してBigDecimalオブジェクトをデータベース列にマップするだけです。

http://i-proving.com/space/Technologies/Hibernate/User+Types+in+Hibernateを参照してください

于 2010-04-12T15:45:14.080 に答える
2

告白:私は個人的にHibernateを使用していませんが、toString()メソッドがtoPlainString()を呼び出すサブクラスMyBigDecimalを作成できますか?

また、BigDecimalのcosntructorにdoubleを渡すことのメリットについても完全にはわかりません。数値が完全に2の累乗の加算で構成されていない限り、doubleは本質的に不正確です(範囲制限あり)。BigDecimalの要点は、doubleに対するこれらの制限を回避することです。

于 2010-04-12T15:03:04.977 に答える