-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: MySQL, Java, Hibernate et les calculs exacts
PostPosted: Tue Apr 24, 2007 4:51 am 
Newbie

Joined: Thu Jan 11, 2007 11:49 am
Posts: 3
Bonjour,

Je suis actuellement en train de développer une application de comptabilité nécessitant des calculs exacts. Ayant rencontré les problèmes d'arrondi qu'on connait avec FLOAT et DOUBLE (qui m'avaient été suggérés par Hibernate), j'ai tenté l'utilisation de DECIMAL(10,2).

Quelle ne fut pas ma surprise de voir que non seulement les problèmes d'arrondis étaient encore présents, mais il semble qu'en plus certaines valeurs soient interdites ! Par exemple, j'arrive à insérer les valeurs de 1.11 à 7.77 mais pas 8.88.

Après passage sur les forums MySQL, la réponse à mon problème semble contenue dans cet article sur IEEE 754 et son interprétation par Java, MySQL et différents compilateurs C/C++.

J'en suis donc réduit pour le moment à mapper mes valeurs comme des entiers et à prier pour que les conversions entier/double (pour l'affichage et la saisie dans mon application) ne posent pas de problème d'arrondi.

Quelqu'un a-t-il une meilleure idée ?

Merci d'avance.

Hibernate version: 3.0.2 ga

Mapping documents: Hibernate Annotations 3.0.2 ga :
Code:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "test_decimal")
public class TestDecimal
{
   @Id
   @Column(name = "dec_value", columnDefinition = "DECIMAL(10,2)")
   double dec_value;

   public double getDec_value()
   {
      return dec_value;
   }

   public void setDec_value(double dec_value)
   {
      this.dec_value = dec_value;
   }
}



Code between sessionFactory.openSession() and session.close():
Code:
for(int i = 0; i < 10; i++)
{
   double value = 0.0d;
   try
   {
      TestDecimal td = new TestDecimal();
      value = (double) (i * 1.11d);
      td.setDec_value(value);
      session.save(td);
   }
   catch(Exception e)
   {
      System.err.println("Erreur à l'insertion pour " + value);
   }
}


Full stack trace of any exception that occurs:
Code:
2007-04-24 10:08:44,086 ERROR [main] org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:301) - Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
   at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at HibernateUtil.commitTransaction(HibernateUtil.java:139)
   at TestTestDecimal.testInsert(TestTestDecimal.java:25)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
   at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
   at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
   at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
   at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
   at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)
   at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
   at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
   at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
   at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.BatchUpdateException: Data truncation: Data truncated for column 'dec_value' at row 1
   at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:657)
   at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:294)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
   ... 29 more


Name and version of the database you are using: MySQL 5.0.37 Community

The generated SQL (show_sql=true): insert into test_decimal (dec_value) values (?)

_________________
Kernel panic: <EOF> from device: /dev/brain0


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.