oracle 将数字 (22,21) 映射到 BigDecimal 时,结果中的 Hibernate 精度损失

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5734036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 23:25:55  来源:igfitidea点击:

Hibernate loss of precision in results when mapping a number (22,21) to BigDecimal

javaoraclehibernatedoublebigdecimal

提问by Riccardo Cossu

I have this column in my Oracle 11g mapped as NUMBER (21,20), which is mapped in Hibernate as:

我在 Oracle 11g 中将此列映射为 NUMBER (21,20),在 Hibernate 中映射为:

@Column(name = "PESO", precision = 21, scale = 20, nullable = false)
public BigDecimal getWeight() {
    return weight;
}

For a particular record for which the value of the column is 0.493 I get a BigDecimal whose value is 0.49299999999. It seems that somewhere there is a loss of precision due (maybe) to a Double or Float conversion, but I couldn't track it down with a simple unit test like this:

对于列值为 0.493 的特定记录,我得到一个 BigDecimal,其值为 0.49299999999。似乎某处由于(可能)由于 Double 或 Float 转换而导致精度损失,但我无法通过这样的简单单元测试来追踪它:

Double d = new Double("0.493");
System.out.println((d));

Any variant of that code, using Float, BigDecimal and various constructors gives the same result: "0.493"... Any hint on how should I map the column to avoid such issues? I'm using Hibernate 3.5.6, with JPA annotations and Hibernate API (that is Session and not EntityManager)

该代码的任何变体,使用 Float、BigDecimal 和各种构造函数都会给出相同的结果:“0.493”...关于我应该如何映射列以避免此类问题的任何提示?我使用的是 Hibernate 3.5.6,带有 JPA 注释和 Hibernate API(即 Session 而不是 EntityManager)

采纳答案by axtavt

It's a result of initializing BigDecimalfrom double:

这是BigDecimal从初始化的结果double

System.out.println(String.format("%21.20f", new BigDecimal(0.493)); 
// Prints 0,49299999999999999378  

So, when BigDecimalinitialized this way is saved in the database, it produces an inaccurate value, which is correctly loaded later.

因此,当以BigDecimal这种方式初始化保存在数据库中时,它会产生一个不准确的值,稍后会正确加载该值。

If BigDecimalis initialized by string or if the value is set directly in Java everything works fine.

如果BigDecimal由字符串初始化或者如果该值直接在 Java 中设置,则一切正常。