Hibernate et de la monnaie de précision
J'ai une hibernate mapping comme suit:
<hibernate-mapping>
<class name="kochman.elie.data.types.InvoiceTVO" table="INVOICE">
<id name="id" column="ID">
<generator class="increment"/>
</id>
<property name="date" column="INVOICE_DATE"/>
<property name="customerId" column="CUSTOMER_ID"/>
<property name="schoolId" column="SCHOOL_ID"/>
<property name="bookFee" column="BOOK_FEE"/>
<property name="adminFee" column="ADMIN_FEE"/>
<property name="totalFee" column="TOTAL_FEE"/>
</class>
</hibernate-mapping>
où InvoiceTVO a les variables définies comme:
private int id;
private Date date;
private int customerId;
private int schoolId;
private float bookFee;
private float adminFee;
private float totalFee;
Quand je fais un insert sur cette table, j'obtiens l'erreur suivante:
Hibernate: insert into INVOICE (INVOICE_DATE, CUSTOMER_ID, SCHOOL_ID, BOOK_FEE, ADMIN_FEE, TOTAL_FEE, ID) values (?, ?, ?, ?, ?, ?, ?)
50156 [AWT-EventQueue-0] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 22001
50156 [AWT-EventQueue-0] ERROR org.hibernate.util.JDBCExceptionReporter - Data truncation: Data truncated for column 'ADMIN_FEE' at row 1
50156 [AWT-EventQueue-0] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
J'ai essayé de changer le type de adminFee à double, et qui ne fonctionne pas non plus. Le problème est, Hibernate n'a réellement procéder à l'insérer correctement, et l'avenir des instructions select travail pour revenir au jeu de valeurs, mais cette erreur m'empêche de faire des traitements sur cette facture.
Les champs bookFee, adminFee, et totalFee sont tous censés être des devises. Ils sont définis dans la base de données MySQL comme decimal(5,2).
Toute aide dans la façon de résoudre ce serait grandement apprécié.
Avez-vous les définir comme séparateur décimal 5,2 ou était-ce de Hibernate?
Je l'ai fait, mais j'ai hérité de la plupart des données, de sorte qu'il n'y avait pas beaucoup d'options.
c'est la "requête SQL" j'ai Hibernate configuré pour afficher les requêtes. Aussi loin que j'ai pu trouver, il n'y a pas un moyen d'afficher les valeurs, il est en fait l'utilisation.
OriginalL'auteur Elie | 2008-12-30
Vous devez vous connecter pour publier un commentaire.
Je voudrais utiliser un type entier (int, long). Jamais drôle de questions avec les gens aussi longtemps que vous pouvez éviter les débordements.
en fait, ils sont plus susceptibles d'avoir une longue underflow.
OriginalL'auteur Phil
Utilisation de float ou double pour de l'argent est absolument inacceptable et peut même être illégal (comme dans la violation des lois ou au moins des règlements). Qui doit être corrigé, l'erreur disparaît. flotteur a une précision limitée et ne peut pas représenter fidèlement la plupart des fractions décimales.
Pour de l'argent, toujours, TOUJOURS utiliser BigDecimal.
Essayé d'utiliser BigDecimal... tous mes calculs me foiré, et maintenant, il enregistre seulement 0 dans tous les domaines.
Oh, et il n'y a pas de questions juridiques avec cette application particulière, les nombres sont arrondis à la fin à la prochaine plus grand entier, mais ils veulent qu'elle a sauvé exactement. Les clients sont conscients de cela.
OriginalL'auteur Michael Borgwardt
Avez-vous essayé d'assigner le type?
Il semble que le problème est avec la précision des données. Parfois, quand vous avez 1.26666666666... la valeur est tronquée.
Vous pouvez également essayer de faire le tour avant d'essayer de l'insérer.
Voir: http://bugs.mysql.com/bug.php?id=7829
Aussi, voir si cela aide:
http://www.ibm.com/developerworks/java/library/j-jtp0114/
OriginalL'auteur OscarRyz
J'ai fini pas à l'aide du flotteur, BigDecimal, ou double. Je suis retourné au client, et ils ont accepté de déposer les pièces d'un cent, depuis le client est toujours à la charge du chiffre arrondi de toute façon, donc il n'y a pas besoin de stocker les pièces de un cent. Cependant, j'ai encore besoin de comprendre comment stocker les monnaies correctement, car ce sera probablement venir de nouveau.
OriginalL'auteur Elie
Personnalisé Hibernate mapping et une définition de classe serait une bonne façon d'aller.
OriginalL'auteur duffymo