Search code examples
javaoracle-databasehibernatedoublebigdecimal

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


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

@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:

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)


Solution

  • It's a result of initializing BigDecimal from double:

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

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

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