Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Java对象序列化到Oracle blob列中有时会导致数据损坏_Java_Oracle_Serialization_Jms_Blob - Fatal编程技术网

将Java对象序列化到Oracle blob列中有时会导致数据损坏

将Java对象序列化到Oracle blob列中有时会导致数据损坏,java,oracle,serialization,jms,blob,Java,Oracle,Serialization,Jms,Blob,我使用序列化将一些对象保存到Oracle Blob列中,然后提取这些对象并在同一次运行或其他运行中使用 序列化/反序列化如下所示: public final class BytesTransformer { static BytesTransformer btInstance = new BytesTransformer(); private ByteArrayOutputStream bytesOutputStream = new ByteArrayOutputStream(); priva

我使用序列化将一些对象保存到Oracle Blob列中,然后提取这些对象并在同一次运行或其他运行中使用

序列化/反序列化如下所示:

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) {
    }
}
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE CONFIGURATION_DEFINITION SET BYTES_DATA=? WHERE NAME=?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
preparedStatement.setObject(1, BytesTransformer.getInstance().getBytes(cfgDef));
preparedStatement.setString(2, cfgDef.getName());
preparedStatement.executeUpdate();
要将数据写入blob列,我使用如下方法:

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) {
    }
}
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE CONFIGURATION_DEFINITION SET BYTES_DATA=? WHERE NAME=?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
preparedStatement.setObject(1, BytesTransformer.getInstance().getBytes(cfgDef));
preparedStatement.setString(2, cfgDef.getName());
preparedStatement.executeUpdate();
要检索数据,请执行以下操作:

public ConfigurationDefinition getConfigurationDefinition(String configName) {
    byte[] bytes = null;
    String sql = "SELECT BYTES_DATA FROM CONFIGURATION_DEFINITION WHERE 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 to extract db records for configuration: " + configName, ex);
        return null;
    } finally {
        getSQLConnector().closeResultSet(rs);
    }
    ConfigurationDefinition aDefinition = (ConfigurationDefinition) BytesTransformer.getInstance().fromBytes(buffer);        
    return aDefinition;
}
大多数时候都没有问题,但有时也很少,而且似乎没有明显的模式:

java.io.StreamCorruptedException: invalid type code: <first_byte>

当我得到第二个错误时,我通常可以在向量中找到从几百字节开始的正确头

我应该提到的是,Oracle模式还包含一些AQ JMS队列,我使用这些队列发送类似的序列化对象,有时从Oracle表中检索这些类型的对象,尽管这两种类型的对象在代码中不可能混在一起

我环顾了有关这些例外情况的讨论,似乎没有任何东西适用于我的案例。就我所知,一切看起来都井然有序,例外情况很少出现


有什么想法吗?

是否可能同时调用这些方法?那么同步可能就是一个例子。尝试使所有方法同步或不依赖实例变量。请注意,序列化对象不应真正用于长期存储。啊,我明白了。。。您的意思是,当输出流为某个线程写入时,另一个线程可能会劫持它,从而损坏消息。这是有道理的。我将同步getBytes和fromBytes方法,看看会发生什么。谢谢或者明智地利用几个当地人。会有更好的表现。一定要把它们清理干净。