2011-04-20 10 views
5

tengo esta columna en mi Oracle 11g asignada como NÚMERO (21,20), que se asigna en Hibernate como:pérdida de hibernación de precisión en los resultados cuando se mapea un número (22,21) a BigDecimal

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

Para un registro particular para el cual el valor de la columna es 0.493 obtengo un BigDecimal cuyo valor es 0.49299999999. Parece que en algún lugar hay una pérdida de precisión debido (tal vez) a una doble conversión o flotar, pero no podía seguir hacia abajo con un simple análisis de unidad de la siguiente manera:

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

Cualquier variante de ese código , usando Float, BigDecimal y varios constructores da el mismo resultado: "0.493" ... ¿Alguna pista sobre cómo debo mapear la columna para evitar tales problemas? estoy usando Hibernate 3.5.6, con las anotaciones JPA y Hibernate API (es decir sesión y no EntityManager)

+0

Parece que esto no fue una falla de hibernación ... Esto es completamente en SquirrelSql, que muestra 0.493 para un valor de 0.49299999999 ... El valor siempre ha sido eso, tanto en el archivo "fuente", tanto en la base de datos , como informa SqlDeveloper. –

Respuesta

3

Es un resultado de la inicialización BigDecimal de double:

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

lo tanto, cuando BigDecimal inicializado este se guarda en la base de datos, produce un valor inexacto, que se carga correctamente más tarde.

Si BigDecimal se inicializa por cadena o si el valor se establece directamente en Java todo funciona bien.

+0

gracias por el ejemplo, probablemente la parte "% 21.20" hace algún truco porque System.out.println (String.format ("% f", new BigDecimal (0.493))); imprime casi bien -> "0,493000". Sin embargo, ese no fue mi caso :-) –

Cuestiones relacionadas