Mike O
August 23rd, 1999, 03:21 PM
This bug has stumped both me and all the "Java Gurus" where I work who I normally run to for help when the goings get tough. Maybe one of you will have the answer?
A field in our DB is a long raw data type. What we store there is a java.util.Hashtable full of name-value pairs of data that is serialized by doing something like this:
public void storeInDB(Hashtable storeThis)
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
oout.writeObject(storeThis);
oout.flush();
String dbData = oout.toString();
storeLongInDB(dbData); // Another method that writes the String to DB
}
Then when we need to get that Hashtable back out we do something like:
publicHashtable getFromDB(Connection con)
{
CallableStatement cs=con.prepareCall("the sql that gets db field");
.........
cs.registerOutParameter(1, java.sql.Types.LONGVARBINARY);
cs.execute();
byte[] data=cs.getBytes(1);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ObjectInputStream oin = new ObjectInputStream(bais);
return ((Hashtable) oin.readObject());
}
Understand so far? Good. Now here is where it gets interesting. This "storeInDB" code was used in the past to add several instances of this field to the DB when called from a web-site front-end, application server back-end type environment. I was tasked to write a stand alone app that gets the Hashtable and either displays its name-value pairs to the user or allows certain values in the hashtable to be added/changed. Getting the hashtable with that 2nd chunk of code seemed to work perfectly well on the data in the DB. But then I tried updating the hashtable. The update wouldn't cause any problems or exceptions right away. But it seems to corrupt the data in the DB. As when I'd later go and try to the view any Hashtable that I previously tried to update, I'd get a wierd exception error that looks like this:
"java.io.InvalidClassException: java.lang.Integer; Local class not compatible: stream classdesc serialVersionUID=<big, long number> local class serialVersionUID=<different big number>".
java.util.Date would also sometimes appear in place of the reference to java.lang.Integer. The exception occurs in the line of getFromDB that looks like this:
return ((Hashtable) oin.readObject());
Even when I don't change anything in the hashtable before puting it back I get this error. It seems like there must be some kind of mistake in the store method that is corrupting the data, but this is the exact same code used previously, if from a different source, that put data in the DB and that doesn't cause any problems if I use my new app only to read, not to change.
Do you have any ideas about what could possibly be causing this? Do you need more detail about what is going on? Please respond in either case. This has us stumped so far and some new ideas would be greatly appreciated.
- Mike
A field in our DB is a long raw data type. What we store there is a java.util.Hashtable full of name-value pairs of data that is serialized by doing something like this:
public void storeInDB(Hashtable storeThis)
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
oout.writeObject(storeThis);
oout.flush();
String dbData = oout.toString();
storeLongInDB(dbData); // Another method that writes the String to DB
}
Then when we need to get that Hashtable back out we do something like:
publicHashtable getFromDB(Connection con)
{
CallableStatement cs=con.prepareCall("the sql that gets db field");
.........
cs.registerOutParameter(1, java.sql.Types.LONGVARBINARY);
cs.execute();
byte[] data=cs.getBytes(1);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ObjectInputStream oin = new ObjectInputStream(bais);
return ((Hashtable) oin.readObject());
}
Understand so far? Good. Now here is where it gets interesting. This "storeInDB" code was used in the past to add several instances of this field to the DB when called from a web-site front-end, application server back-end type environment. I was tasked to write a stand alone app that gets the Hashtable and either displays its name-value pairs to the user or allows certain values in the hashtable to be added/changed. Getting the hashtable with that 2nd chunk of code seemed to work perfectly well on the data in the DB. But then I tried updating the hashtable. The update wouldn't cause any problems or exceptions right away. But it seems to corrupt the data in the DB. As when I'd later go and try to the view any Hashtable that I previously tried to update, I'd get a wierd exception error that looks like this:
"java.io.InvalidClassException: java.lang.Integer; Local class not compatible: stream classdesc serialVersionUID=<big, long number> local class serialVersionUID=<different big number>".
java.util.Date would also sometimes appear in place of the reference to java.lang.Integer. The exception occurs in the line of getFromDB that looks like this:
return ((Hashtable) oin.readObject());
Even when I don't change anything in the hashtable before puting it back I get this error. It seems like there must be some kind of mistake in the store method that is corrupting the data, but this is the exact same code used previously, if from a different source, that put data in the DB and that doesn't cause any problems if I use my new app only to read, not to change.
Do you have any ideas about what could possibly be causing this? Do you need more detail about what is going on? Please respond in either case. This has us stumped so far and some new ideas would be greatly appreciated.
- Mike