Oracle knows nothing about Java

Posted by Mike Haller on Saturday, March 24. 2007 at 14:53
Let's pretend Oracle makes some good database stuff. What they apparently do really bad: Java drivers. The Oracle Thin JDBC Drivers are so bad, that there is a whole bunch of vendors implementing their own drivers. Commercial drivers.

(We are not talking about some opensource guys trying to circumvent a license agreement by implementing a free version, so they can put drivers into a free tool. No we're talking about high-quality and sometimes high-priced replacement products.)

I didn't believe what I was hearing from friends, but this week, i trapped into it on my own. Let's suppose you've got some code which inserts a large numeric value like 12 Million Euro into your companies database...
BigDecimal value = BigDecimal.valueOf(12300000.0);
// value.toString is "1.23E+7"
oracleDB.insert(value);


As you can see, BigDecimal uses the exponent notation to represent the value internally in this case. The Oracle driver uses BigDecimal.toString() to get exactly this representation on Java 1.5.

The driver also checks for the existence of "E" in the value toString(). After decompiling the current thin driver 10.2.0.3, I found that in oracle.jdbc.driver.BigDecimalBinder:

public void testOracleDriver() throws Exception {
	
// Input Variables
int eIndex = 0;
String sval = "1.23E+7";
		
// Oracle code from BigDecimalBinder
if((eIndex = sval.indexOf("E")) != -
{
     String s = "";
     int zeros = 0;
     BigDecimal val2 = null;
     String eValue = sval.substring(eIndex + 1);
     String intVal = sval.substring(0, eIndex);
     val2 = new BigDecimal(intVal);
     boolean isNegative = eValue.charAt(0) == '-';
     eValue = eValue.substring(1);
     zeros = Integer.parseInt(eValue);
     int dotIndex = val2.toString().indexOf(".");
     if(dotIndex != -1)
     {
         double pow = Math.pow(10D, dotIndex);
         val2 = val2.multiply(new BigDecimal(pow));
         zeros -= dotIndex;
     } else
     if(isNegative)
         zeros--;
     String sval2 = val2.toString();
     sval2 = sval2.substring(0, sval2.length()
               - (dotIndex + 1));
     s = isNegative ? "0." : sval2;
     for(int i = 0; i < zeros; i++)
         s = s + "0";
      if(isNegative)
         s = s + sval2;
     sval = s;
 }
 // Oracle code from BigDecimalBinder

// Succeeds incorrectly:
assertEquals("12.000000",sval);

// Fails
assertEquals("12300000",sval);

}


In the end, you end up with the value 12 in your database -- you just lost 12299988 bucks without any notice - no error message, no exception, nothing.

What I do like most: Even so, their driver 10.2.0.3 is Java5 certified! Yes, it is officially certified. I wonder who certified this piece of crap and whether they got further than the usual Hello-World example.

In their support forum, there seem to be announces to a fixed version 10.2.0.4, which won't be released publicly for the next few months. Is there any reason to hold back a driver update that long which has a really serious flaw?

Thanks Oracle!

John had the same problem and asks for people who suffer from the same issue. Let him know. There is a discussion on the Oracle Forum where the lead developer replies.



Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications
 
Submitted comments will be subject to moderation before being displayed.
 

About

My name is Mike Haller and I'm a software developer and architect at Bosch Software Innovations in Germany. I love programming, playing games and reading books. I like good food, making photos and learning and mentoring about the craftsmanship of commercial software development. Stack Overflow profile for mhaller

Quicksearch