Pages

Friday, May 8, 2009

Oracle 10g JDBC and Java 5

In addition to the previous bug with Oracle 10g JDBC driver v10.1.0.4 and Java 5, when instead of a very small number a very large number gets inserted, we encountered another bug, which was kind of the opposite. This time the exact version of Oracle driver is 10.1.0.5.

Here's a sample code:
BigDecimal decimal = new BigDecimal("1.03+7");
PreparedStatement stmt = .... 
stmt.setBigDecimal(decimal);
stmt.update("...some sql...");
After the transaction is commited, and we do a query for the result we get .... 10 (!)

inserted 1.03+7 but the result is 10


We cannot rewrite the application, as it already has a lot of Java 5 features in it. One option could be to use retrotranslator and run the application with Java 4. But the problem is that we already use some frameworks that make use of Java 5 API and we cannot overcome the problem just by translating the bytecodes to the older JVM.


Here's the solution I discovered:

When using the scientific notation for instantiating BigDecimal, calling a toString() method will be:

BigDecimal decimal = new BigDecimal("1.03+7");
System.out.println(decimal);
>> 1.03+7

But changing the scale will produce something different:
BigDecimal decimal = new BigDecimal("1.03+7");
System.out.println(decimal.setScale(2));
>> 10300000.00

That's it! You just can set scale for the BigDecimal that you are about to insert into Oracle database :) So far we're good with this solution, although it looks like a crap.

No comments:

Disqus for Code Impossible