我在Oracle 11g中将此列映射为NUMBER(21,20),它在Hibernate中映射为:
@Column(name = "PESO", precision = 21, scale = 20, nullable = false)
public BigDecimal getWeight() {
return weight;
}
对于列的值为0.493的特定记录,我得到一个BigDecimal,其值为0.49299999999。 似乎某个地方由于(可能)Double或Float转换而导致精度损失,但我无法通过这样的简单单元测试来跟踪它:
Double d = new Double("0.493");
System.out.println((d));
该代码的任何变体,使用Float,BigDecimal和各种构造函数都会得到相同的结果:“0.493”...... 有关如何映射列以避免此类问题的任何提示? 我正在使用Hibernate 3.5.6,带有JPA注释和Hibernate API(即Session而不是EntityManager)
答案 0 :(得分:3)
这是从BigDecimal
初始化double
的结果:
System.out.println(String.format("%21.20f", new BigDecimal(0.493));
// Prints 0,49299999999999999378
因此,当BigDecimal
初始化时,这种方式被保存在数据库中,它会产生一个不准确的值,以后会正确加载。
如果BigDecimal
是由字符串初始化的,或者如果直接在Java中设置了值,那么一切正常。
答案 1 :(得分:0)
对我来说,获胜的解决方案是基于 How do I map a BigDecimal in Hibernate so I get back the same scale I put in? 的解决方案:
private final int SCALE = 2;
private final RoundingMode ROUNDING_MODE = RoundingMode.CEILING;
@Column(name = "value", precision = 8, scale = 2)
private BigDecimal value;
public BigDecimal getValue() {
return value.setScale(SCALE, ROUNDING_MODE);
}
所以,我只是提供了一个执行大十进制自动整理的 getter。