0

I need to save in SQL Server 2008 table a serialized Object Stream and then deserialize it. The problem arise when i deserialize..I get the following Exception:

Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: 5B424065
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)

I use JTDS-1.2.4 (not the last JTDS Driver Type 4)

In table i save in a column type -> NVARCHAR(MAX), i have this value for e.g.

[B@e3fd79

i read the value above (jtds give me a sql.Clob) and i try to deserialize it

My Java Code:

    DocumentObjectHolder doc = new DocumentObjectHolder(xmldata, "data.xml", TYPE.XML, xmldata.getBytes("UTF-8"));
//SERIALIZE DocumentObjectHolder 
            ByteArrayOutputStream bof = new ByteArrayOutputStream();
            ObjectOutputStream serialize = new ObjectOutputStream(bof);
            serialize.writeObject(doc);
            SQLDbManagerFactory.setDbConnectionParameters(dbUri, username, password, driver);
            SQLDBManager factoryDb = SQLDbManagerFactory.getSQLDBManager();

            factoryDb.execSQL("INSERT INTO MY_DOCUMENTS (DATA,DOCUMENT_TYPE,IS_READY,DO_EMIT,IS_EMITTED)" + 
            " VALUES ( '" + bof.toByteArray() + "','" + TYPE.XML.name() + "', 0, 0, 0)");

            RecordSet rs = (RecordSet) factoryDb.execSQL("SELECT TOP 1 DATA FROM MY_DOCUMENTS");
            if (rs != null && rs.getLength() > 0){
//DESERIALIZE in DocumentObjectHolder 
                Clob objris = (Clob)rs.get(0, 0);  
                InputStream in = objris.getAsciiStream();
                byte[] b = new byte[in.available()];
                in.read(b);
                ByteArrayInputStream bais = new ByteArrayInputStream(b);
                ObjectInputStream ins = new ObjectInputStream(bais);
                DocumentObjectHolder mc =(DocumentObjectHolder)ins.readObject();
                System.out.println("Object in value ::"+mc.toString());
                ins.close();
                in.close();
            }

SQLDBManager is my private library ..

I suppose it would be a Blob (byte blob) not a Clob (char lob), so i tried to change nvarchar(max) to varbinary(500) because i read here: http://jtds.sourceforge.net/typemap.html

but i get the following exception:

Exception in thread "main" java.sql.SQLException: Invalid SQL statement or JDBC escape, terminating ']' not found.
at net.sourceforge.jtds.jdbc.SQLParser.parse(SQLParser.java:1155)
at net.sourceforge.jtds.jdbc.SQLParser.parse(SQLParser.java:156)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.<init>(JtdsPreparedStatement.java:107)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareStatement(ConnectionJDBC2.java:2456)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareStatement(ConnectionJDBC2.java:2414)

What's wrong?

user207421
  • 305,947
  • 44
  • 307
  • 483
robyp7
  • 481
  • 2
  • 7
  • 25

1 Answers1

1

Lets start with the "header" 5B424065.

If you translate that as ASCII, you get '[' 'B' '@' 'e' ... Does that look familiar?

Now your the string "[B@e3fd79". What is it?

First of all, it is NOT a valid serialization. In fact, what it is ... is what you get when you call toString() on an byte[].

  • The "[B" component is the type signature for a byte[].

  • The "e3fd79" component is an identity hash code ... which is typically based on the arrays address, at the time that the identity hash code was first requested.

  • Most important, this string does not encode the byte array's contents/

So where is it coming from?

It comes from this expression: bof.toByteArray(). That is not the right way to turn the contents of the byte array into a string.

What is the right way?

It depends on the SQL type of the "DATA" column. And yes - @EJP is spot on. You should not be trying to stringify the byte array at all. Use a PreparedStatement an a parameter placeholder (?).

If the column type is BINARY or VARBINARY, then you should be able to pass the byte[] as-is. For a full listing for the type mappings of jDTS, refer to the documentation.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • DATA was nvarchar(max) then i changed to varbinary and then i tried binary but i get the same DataTruncated Ex.. So it's wrong using toByteArray() because it write the String byte or is wrong sql data type? – robyp7 May 05 '15 at 16:06
  • maybe i have to use string instead of byte like in this post? -> http://stackoverflow.com/questions/134492/how-to-serialize-an-object-into-a-string – robyp7 May 05 '15 at 19:29
  • @robyp7 You shouldn't be turning the byte array into a string at all. You should be using `PreparedStatement` with a ? marker. – user207421 May 05 '15 at 22:50