*
The moose likes I/O and Streams and the fly likes Storing serialized objects Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » I/O and Streams
Bookmark "Storing serialized objects" Watch "Storing serialized objects" New topic
Author

Storing serialized objects

Tim Williams
Greenhorn

Joined: Feb 12, 2001
Posts: 27
I have a requirement to store a serialized object in a database.
I have serialized an object to a byte array. I tried constructing a String from the byte array so I could write the String to my database. However, the character encoding alters some of the values such that I cannot call myString.getBytes() and deserialize the object from the resulting array.
Can anybody suggest a solution?
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Are you using the toString() method of the ByteArrayOutputStream class?


Associate Instructor - Hofstra University
Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog
Tim Williams
Greenhorn

Joined: Feb 12, 2001
Posts: 27
Yes. This is one of the things I have tried.
Sample code:

This is the exception I get:

java.io.InvalidClassException: java.util.Date; Local class not compatible: stream classdesc serialVersionUID=7523895402267505689 local class serialVersionUID=7523967970034938905
java.lang.Throwable(java.lang.String)
java.lang.Exception(java.lang.String)
java.io.IOException(java.lang.String)
java.io.ObjectStreamException(java.lang.String)
java.io.InvalidClassException(java.lang.String, java.lang.String)
void java.io.ObjectStreamClass.validateLocalClass(java.lang.Class)
void java.io.ObjectStreamClass.setClass(java.lang.Class)
java.io.ObjectStreamClass java.io.ObjectInputStream.inputClassDescriptor()
java.lang.Object java.io.ObjectInputStream.readObject(boolean)
java.lang.Object java.io.ObjectInputStream.readObject()
int java.io.ObjectInputStream.inputObject(boolean)
java.lang.Object java.io.ObjectInputStream.readObject(boolean)
java.lang.Object java.io.ObjectInputStream.readObject()
void serialization.Convert.serialize()
void serialization.Convert.main(java.lang.String [])

[Peter: I'm editting this post to make it easier to read the code.]
Note that this does work for some classes. Just not for those that generate byte -127, for example, in the ByteArrayOutputStream.
Tim.
[This message has been edited by Peter Tran (edited February 13, 2001).]
Peter Tran
Bartender

Joined: Jan 02, 2001
Posts: 783
Tim,
1. Rather than creating a String object and getting a byte[] from the String object, you should get the byte[] directly from the ByteArrayOutputStream.
2. When you de-serialized the object, you need to cast back to the actual object you wrote out.

-Peter
Tim Williams
Greenhorn

Joined: Feb 12, 2001
Posts: 27
Peter,
I can see this will work as far as Serialization goes. The catch is I have a requirement to persist the byte array in a database. Circumstances beyond my control dictate that the datatype in the database is a DB2 LONGVARCHAR, hence the attempt to convert to a String.
Tim.
Peter Tran
Bartender

Joined: Jan 02, 2001
Posts: 783
Tim,
Unless you can get the datatype changed in the database, I don't think you can do it. The String object will corrupt your byte[].
-Peter
Peter Tran
Bartender

Joined: Jan 02, 2001
Posts: 783
Tim,
The reason why is a String object holds an internal char[] buffer. Remember that char is unicode in JAVA which stores it as 2 bytes! There might be a 1 byte -> 2 bytes conversion when you execute a new String(byte[]).
-Peter
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Figured it out...
The problem is that when you create the String, it assumes that it is using ISO-646-US encoding which only uses the first 7 bits. This causes the loss of the first bit of each byte.
Try this:
********************************
byte[] b = { -53, 89, 83, -115};
System.out.println(b[0] + " " + b[1] + " " + b[2] + " " + b[3]);
String s = new String(b);
b = s.getBytes();
System.out.println(b[0] + " " + b[1] + " " + b[2] + " " + b[3]);
*********************************
The output of this code is:
***********
-53 89 83 -115
-53 89 83 63
***********
But there is a solution. You need to tell it to use "ISO-8859-1" to do the encoding! So your code looks like this:

Peter Tran
Bartender

Joined: Jan 02, 2001
Posts: 783
Way Thomas!
Peter Tran
Bartender

Joined: Jan 02, 2001
Posts: 783
The interesting thing would be to see if writing the String object to the DB2 database remains valid on the roundtrip. That would be a major bummer if DB2 corrupts the char[] stream. Okay, Tim it's up to you to validate the roundtrip to the database. Let us know!
-Peter
Tim Williams
Greenhorn

Joined: Feb 12, 2001
Posts: 27
Thanks for your help everybody!
The code page ISO-8859-1 is the only one that works - I ran them all through.
The DB2 problem is as suspected - it runs its own code page conversion on the string. It comes as no surprise that this code page is not available with my installation of DB2!
I will pursue this further with our DBAs and post an update when I have an answer - I know it's not Java exactly but I thinks it's still relevant here.
Thanks again,
Tim.
Peter Tran
Bartender

Joined: Jan 02, 2001
Posts: 783
Good luck hombre. Come back and let us know if you succeed.
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
Yes, absolutely let us know as I am sure this will come up again!
I think I might try this on some other databases to see if it works.

[This message has been edited by Thomas Paul (edited February 13, 2001).]
sunil choudhary
Ranch Hand

Joined: Nov 10, 2000
Posts: 141

Like a Great Climax in Action Movie...
Sheer Joy!!!
watching the post
Good work... all of you.
Sunil CHoudhary
[This message has been edited by sunil choudhary (edited February 16, 2001).]


"Learning is weightless, a treasure you can always carry easily." -Chinese Proverb
Peter Tran
Bartender

Joined: Jan 02, 2001
Posts: 783
Sunil,
You need to get out more and watch some real action movies.
You are right. This topic was pretty cool. It felt like Thomas, Tim, and I were doing XP pair-programming.
-Peter
sunil choudhary
Ranch Hand

Joined: Nov 10, 2000
Posts: 141

Hi Peter I am very happy.. just yesterday I got the first job of my life through Campus interviews (I still have 2 month to finish the course of MIS from DAVV Indore) ( I am a BE Mechanical Engineer passed in 1998.)
They tell me that there is a Training for 6 months and and then I will be ready to Rock and Roll.
I want to thank people at javaranch
also John Coxey... for his replies in posts
watch my inspirational Chicken soup for soul here http://www.javaranch.com/ubb/Forum37/HTML/000286.html http://www.javaranch.com/ubb/Forum37/HTML/000292.html
Once again thanks for the excellent stuff.. on Ranch...I will be contributing to the ranch with more energy now...
Excellent People!!!
Sunil
[This message edited for adding Links by sunil choudhary (edited February 17, 2001).]
[This message has been edited by sunil choudhary (edited February 17, 2001).]
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
I wonder if Tim ever got this to work.
Tim Williams
Greenhorn

Joined: Feb 12, 2001
Posts: 27
I hadn't forgotten you all!
The short answer is no - but I am still trying. Database Administrators at our company are thin on the ground - to the point of being transparent.
The bottom line at present is I can't make it work, and it doesn't look like I will be able to.
In summary, I can get a valid String but the Database messes it up. I can store it as bit data on a DB2 Varchar field, which means I have no problems getting a String in to the database, but then I can't get it out as a String, it would involve some manual conversion. Not what I wanted.
I still have a couple of irons in the fire (a Java stored procedure maybe), but since we have decided to go with an alternative solution they are not top priority at the moment.
Thank you all for the support,
Tim.
(If I get a solution, and this thread is still up, I will post an answer!!!)
T Bush
Greenhorn

Joined: Jul 31, 2000
Posts: 13
I'm implemented something very similar. First, your serialized objects need to contain something like this....
/** used for serialization compare - use any hex number**/
static private final long serialVersionUID = 0x2b3dBf00F00db2d3L;
This should get rid of you java.io.InvalidClassException: java.util.Date; Local class not compatible: stream classdesc serialVersionUID=7523895402267505689 local class serialVersionUID=7523967970034938905 problems...
As for the database, check out this code...
Connection myConn = aTransaction.getConnection();
StringBuffer myBuffer = new StringBuffer();
// serialize and get a byte array. Make inputstream for object
byte[] myBuf = serializeUserPreference(myClass);
ByteArrayInputStream baiStream = new ByteArrayInputStream(myBuf);
myBuffer.append("INSERT INTO ")
.append(TABLE_NAME)
.append("(")
.append(getInsertColumns())
.append(") ")
.append("VALUES (?, ?, ?, ")
.append(FhcDataManagement.DATE_TIME)
.append(")");
PreparedStatement ps = myConn.prepareStatement(myBuffer.toString());
ps.setLong(1, myClass.getKey());
ps.setLong(2, myClass.getParentKey());
ps.setBinaryStream(3, baiStream, myBuf.length);

ps.execute();
/* serialize obj */
private byte[] serializeUserPreference(UserPreference obj) throws FhcException {
byte[] result;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
result = baos.toByteArray();
oos.flush();
oos.close();
}
catch(Exception e) {
throw new FhcException(e);
}
return result;
}

Let me know if this helps...
------------------
Todd Bush
AIM: RalphWiggam14
[This message has been edited by T Bush (edited April 20, 2001).]


Todd Bush<BR>AIM: RalphWiggam14
Tim Williams
Greenhorn

Joined: Feb 12, 2001
Posts: 27
So what was your database?
And what was your table definition? Can you do a setBinaryStream in to a Varchar column? (Recall I am constrained by an existing DB2 table definition.)
Also, does you mean the characters generated by the SerialUID are the only ones that are giving problems with the code page? I suspect not as adding a java.util.Date property was the one that seemed to start causing me problems, until then it was all just fine....
I also know that a 'database' such as MSAccess will work with no problems as I don't think it does any code page conversions.
Still fighting!!!
Tim.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Storing serialized objects
 
Similar Threads
Regarding the Soap Message
Reading a blob object from a database
character encodings
How to convert RAW(32) to String?
storing a serialized object in a String?