2009-10-16 9 views
1

J'ai un double que j'essaie d'enregistrer dans une colonne numérique postgres. La valeur que j'essaye de sauver est 151.33160591125488, et j'ai vérifié que c'est en fait l'argument étant reçu par les internes d'Hibernates pré-insèrent.Hibernate arrondit mon double?

Cependant, la valeur dans l'insertion de la base de données est 151,331605911255, c'est-à-dire arrondie à 12dp.

Je sais que ma colonne est de l'échelle de droite, comme il est une colonne numérique sans restriction et les suivantes ...

update tbl set col=151.33160591125488 

... a l'effet désiré. Donc, le coupable doit être Hibernate ou le pilote postgres-JDBC.

Des idées?

EDIT:

org.hibernate.dialect.PostgreSQLDialect:

registerColumnType(Types.DOUBLE, "float8"); 

et

select cast (151.33160591125488 as float8); 

= 151,331605911255

le comportement par défaut pour le double est donc incorrect, comme ne sauvegarde pas toujours le double fourni.

Est-ce que quelqu'un sait comment obtenir hibernate pour utiliser le type de colonne "numérique" dans postgres?

+0

Vous n'avez pas vraiment donné suffisamment de détails sur le côté hibernation. Le mappage peut spécifier la précision et l'échelle. par exemple:

+0

Merci brian, je vais essayer mais cela réduirait l'évolutivité de mon application, tout simplement parce que Hibernate se comporte mal. java double ne restreint pas, postgres ne restreint pas, pourquoi hiberner? – pstanton

+0

J'ai essayé avec précision = "30" échelle = "20" qui aurait dû être en abondance, même résultat. si mauvais conseil. – pstanton

Répondre

3

Chaque fois que des questions de précision utilisent java.math.BigDecimal. Ce answer discute cela en détail.

+0

merci, je suis sûr que cela fonctionnerait (et je vais le tester), mais comme je ne fais aucune arithmétique sur ce nombre, les pièges de l'IEEE ne s'appliquent pas.donc le double est parfaitement adapté à mes besoins. cela n'a toujours pas de sens pour Hibernate de modifier par inadvertance une information que je lui demande de persister. – pstanton

+0

à partir de JLS (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html) ** Les types à virgule flottante sont float, dont les valeurs incluent le flottant 32 bits IEEE 754 numéros de point, et double, dont les valeurs incluent les nombres à virgule flottante IEEE 754 64 bits. ** Peu importe si vous avez fait des calculs ou non, vous avez toujours les pièges. – n002213f

+0

comment ça va? J'ai un double exact. j'en ai besoin persisté. ça ne change pas. si hibernate ne l'a pas lancé en float8, il serait conservé correctement. Dans mon expérience, vous avez seulement des problèmes avec les choses IEEE 754 lorsque vous faites de l'arithmétique sur ces chiffres. Prouve moi le contraire. montre un exemple. – pstanton

2

Java double n'est pas vraiment approprié pour des opérations mathématiques précises. Utilisez BigDecimal à la place. Hibernate supporte comme l'un des basic types:

<property name="amount" type="big_decimal" /> 
+0

merci, voir mon commentaire sur le post de n002213f. – pstanton

+1

Peu importe que vous effectuiez de l'arithmétique ou non. Vous ** NE POUVEZ PAS ** compter sur le «double» pour ** tout ** type de précision. En outre, vous avez demandé comment mapper au type "NUMERIC" - c'est ce que "big_decimal" est mappé. – ChssPly76

+0

montrez-moi un exemple de double changement sans arithmétique en cours d'exécution. – pstanton