Serializing Java objects into Oracle blob columns sometimes results in corrupted data -
i use serialization save objects oracle blob columns extract , use in same run or in other runs.
the serialization/deserialization looks this:
public final class bytestransformer { static bytestransformer btinstance = new bytestransformer(); private bytearrayoutputstream bytesoutputstream = new bytearrayoutputstream(); private objectoutputstream objectoutputstream; private bytearrayinputstream bytesinputstream; private objectinputstream objectinputstream; public static bytestransformer getinstance() { return btinstance; } private void initialiseinputstreams(byte[] bytes) throws ioexception { bytesinputstream = new bytearrayinputstream(bytes); objectinputstream = new objectinputstream(bytesinputstream); } private void initialiseinputstreams(inputstream bytes) throws ioexception { objectinputstream = new objectinputstream(bytes); } public byte[] getbytes(serializable sobject) throws ioexception { bytesoutputstream.reset(); objectoutputstream = new objectoutputstream(bytesoutputstream); objectoutputstream.writeobject(sobject); objectoutputstream.close(); return bytesoutputstream.tobytearray(); } public object frombytes(byte[] databytes) throws ioexception, classnotfoundexception { initialiseinputstreams(databytes); object sobject = objectinputstream.readobject(); closeinputstreams(); return sobject; } public object frombytes(inputstream databytes) throws ioexception, classnotfoundexception { initialiseinputstreams(databytes); object sobject = objectinputstream.readobject(); closeinputstreams(); return sobject; } private void closeinputstreams() { try { if (objectinputstream != null) { objectinputstream.close(); } if (bytesinputstream != null) { bytesinputstream.close(); } } catch (ioexception ex) { } }
to write data blob column use this:
preparedstatement preparedstatement = connection.preparestatement("update configuration_definition set bytes_data=? name=?", resultset.type_forward_only, resultset.concur_updatable); preparedstatement.setobject(1, bytestransformer.getinstance().getbytes(cfgdef)); preparedstatement.setstring(2, cfgdef.getname()); preparedstatement.executeupdate();
to retrieve data:
public configurationdefinition getconfigurationdefinition(string configname) { byte[] bytes = null; string sql = "select bytes_data configuration_definition name = '" + configname + "'"; resultset rs = getsqlconnector().executequerywithoutnoise(sql); try { if (rs == null || !rs.next()) { return null; } blob blob = rs.getblob(blobcolumnname); bytes = blob.getbytes(1, (int) blob.length()); } catch (sqlexception ex) { gatewaylogger.error("unable extract db records configuration: " + configname, ex); return null; } { getsqlconnector().closeresultset(rs); } configurationdefinition adefinition = (configurationdefinition) bytestransformer.getinstance().frombytes(buffer); return adefinition; }
most of time there no problem, (quite rarely) , seemingly no discernable pattern either:
java.io.streamcorruptedexception: invalid type code: <first_byte>
or
java.io.streamcorruptedexception: invalid stream header: <first_four_bytes>
when second error can find correct header starting few hundred bytes vector.
i should mention oracle schema holds aq jms queues use send serialized objects through , on couple of occasions objects of types retrieved oracle table though there no way 2 mixed in code.
i've looked around @ discussions exceptions , nothing seems apply case. looks in order far can tell , exceptions pop rarely.
any ideas?
Comments
Post a Comment