-1

I am getting following error

Caused by: java.lang.IllegalArgumentException: Underflow at oracle.jdbc.driver.OraclePreparedStatement.setDoubleInternal(OraclePreparedStatement.java:6604) ~[ojdbc7-12.1.0.2.0-p0.jar:12.1.0.2.0] at oracle.jdbc.driver.OraclePreparedStatement.setDouble(OraclePreparedStatement.java:6574) ~[ojdbc7-12.1.0.2.0-p0.jar:12.1.0.2.0]*

This happens when one of the double value in my data object is null/illegal. This happens when session.flush being called. The problem is my data object have composition of other data object and N number of collection elements.

It's difficult to find which double data member is giving the issue. I have enabled the persistence log and not able to see the query being formed for update statement. Don't have anything on log except the above line. I have put breakpoints on all the get member functions. The exception didnt happen when session.update is getting called. It happens when session.flush being called. Also sometimes I get session time out as I have huge number of data elements. So debugging all the data elements was bit difficult.

How to find which member is giving the issue ?

samnaction
  • 1,194
  • 1
  • 17
  • 45
  • Give the data member a proper `toString()` outputting all members (eg using `org.apache.commons.lang3.builder.ReflectionToStringBuilder`), and log that when the exception occurs. – daniu Jun 05 '18 at 10:53
  • Debug your code. Using correct breakpoint, you will get the value at the moment the exception occurs. Of course, you should format your numeric value to fit the limit of the database. – AxelH Jun 05 '18 at 10:54
  • I have debugged and put breakpoint on all the get elements, session.update goes fine. Session.flush is giving me the issue – samnaction Jun 05 '18 at 10:55
  • That means a commit is waiting, that's why it failed on the `flush`. You could check to disable the transaction mode (hibernate is not my forte...) – AxelH Jun 05 '18 at 11:00
  • @AxelH if commit is waiting wont I be getting a different exception than underflow ? – samnaction Jun 06 '18 at 05:13
  • Possible duplicate of [Oracle JDBC: underflow in double](https://stackoverflow.com/questions/40482557/oracle-jdbc-underflow-in-double) – AxelH Jun 06 '18 at 05:19
  • It was bothering me that it was coming frome `OraclePreparedStatement.setDouble`. I guess dup should give you the reason. If not, please provide a [mcve]. – AxelH Jun 06 '18 at 05:20

2 Answers2

0

Do you use something like Hibernate? You could enable debug or trace log to show the sql-statements that are generated. It turns out even Oracle JDBC has log that can be enabled:

From https://stackoverflow.com/a/40491028/66207 :

  1. Place the trace-enabled ojdbc jar file in your classpath. Quote from the linked Oracle page: "To get log output, you must use the debug JAR files, which are indicated with a "_g" in the file name, like ojdbc5_g.jar or ojdbc6_g.jar." My Oracle 11g installation contained
  2. Create a logging.properties file as described on the linked Oracle page, and adjust the logging levels to your needs. Example:

    .level=SEVERE oracle.jdbc.level=FINEST
    oracle.jdbc.handlers=java.util.logging.FileHandler
    java.util.logging.FileHandler.level=FINEST
    java.util.logging.FileHandler.pattern=jdbc.log
    java.util.logging.FileHandler.count=1
    

    java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

  3. Add the JVM properties "-Doracle.jdbc.Trace=true -Djava.util.logging.config.file=logging.properties" to the java startup command for your JDBC application.

The JDBC application should now produce a file named jdbc.log which should contain the desired information. In some cases it can be necessary to specify the full path to the logging.properties file.

Or the Hibernate Solution from https://stackoverflow.com/a/1713464/66207 :

You need to enable [logging][2] for the the following categories:

  • org.hibernate.SQL   - set to debug to log all SQL DML statements as they are executed
  • org.hibernate.type - set to trace to log all JDBC parameters

So a log4j configuration could look like:

# logs the SQL statements
log4j.logger.org.hibernate.SQL=debug 

# Logs the JDBC parameters passed to a query
log4j.logger.org.hibernate.type=trace 

The first is equivalent to hibernate.show_sql=true legacy [property][1], the second prints the bound parameters among other things.

Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86
keuleJ
  • 3,418
  • 4
  • 30
  • 51
  • 1
    Please add more information on how to use those soltuions. See [answer]. You barely have a comment for the moment (This is assuming it use `Hibernate` where I would most likely see a pure JDBC solution) EDIT: nice catch for `Session.flush` of hibernate ! – AxelH Jun 05 '18 at 10:53
  • Added a JDBC-only solution – keuleJ Jun 05 '18 at 10:58
  • ... and one for hibernate – keuleJ Jun 05 '18 at 11:00
0

I was able to print the persistence log after enabling the following property :

sessionFactory-> cacheAccess->SessionFactory->jdbcservices->sqlStatementLogger->logToStdOut --> set this to TRUE.

Now the logs were printed and I was able to see the data which was causing the issue.

samnaction
  • 1,194
  • 1
  • 17
  • 45