对象序列化后,写入Oracle Blob字段:“无法从套接字读取更多的数据”

03-09-15 mellon
..............

StringBuffer sb=new StringBuffer("insert into LF_CTRL_PLAN(plan_no,fcno,itemid,netid,fore_category,plan_name,creator,plan_ser,createdate,fctype,foreType,recommendation) values(?,?,?,?,?,?,?,?,?,?,?,?)");

PreparedStatement preStat=conn.prepareStatement(sb.toString());

//对象序列化后,存入数据库

ByteArrayOutputStream byteOut=new ByteArrayOutputStream();

ObjectOutputStream outObj=new ObjectOutputStream(byteOut);

outObj.writeObject(this) ;

final byte[] objbytes=byteOut.toByteArray();

InputStream in=new InputStream(){

int objbytesIndex=0;

public int read(){

while(objbytesIndex<objbytes.length){

return objbytes[objbytesIndex++];

}

return -1;

}

};

preStat.setBinaryStream(8,in,objbytes.length);

...........

preStat.executeUpdate() ;

return plan_no;

}

mellon
2003-09-15 18:04
java.sql.SQLException: 无法从套接字读取更多的数据

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:180)

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:222)

at oracle.jdbc.dbaccess.DBError.check_error(DBError.java:944)

at oracle.jdbc.ttc7.MAREngine.unmarshalUB1(MAREngine.java:741)

at oracle.jdbc.ttc7.MAREngine.unmarshalSB1(MAREngine.java:700)

at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:373)

at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1451)

at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:862)

at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:1846)

at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1771)

at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2361)

at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:422)

at com.nbw.forecast.Plan.save(Plan.java:274)

at com.nbw.forecast.Plan.save(Plan.java:219)

at com.nbw.forecast.ForecastResult.save(ForecastResult.java:87)

at com.nbw.forecast.helper.HelperSaveForecastResult.process(HelperSaveForecastResult.java:27)

at com.nbw.forecast.ForecastServlet.doGet(ForecastServlet.java:69)

at com.nbw.forecast.ForecastServlet.doPost(ForecastServlet.java:76)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)

我原本使用的是

ByteArrayOutputStream byteOut=new ByteArrayOutputStream();

ObjectOutputStream outObj=new ObjectOutputStream(byteOut);

outObj.writeObject(obj) ;

preStat.setBytes(8,byteOut.toByteArray());

使用数组直接输入,提示出错为:

java.sql.SQLException: 数据大小超出此类型的最大值: 4610

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:180)

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:222)

at oracle.jdbc.ttc7.TTCItem.setArrayData(TTCItem.java:99)

at oracle.jdbc.dbaccess.DBDataSetImpl.setBytesBindItem(DBDataSetImpl.java:1761)

at oracle.jdbc.driver.OraclePreparedStatement.setItem(OraclePreparedStatement.java:856)

at oracle.jdbc.driver.OraclePreparedStatement.setBytes(OraclePreparedStatement.java:1825)

robbin
2003-09-15 18:41
Oracle Blob 不是这么用滴...

robbin
2003-09-15 18:44
应该是这样用滴...

import java.sql.*;
import java.io.*;
import oracle.sql.*;
public class WriteBlob {

  public static void main(String[] args) {

    try {
      DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
      Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","fankai","fankai");
      conn.setAutoCommit(false);

      BLOB blob = null;

      PreparedStatement pstmt = conn.prepareStatement("insert into javatest(name,content) values(?,empty_blob())");
      pstmt.setString(1,"fankai");
      pstmt.executeUpdate();
      pstmt.close();

      pstmt = conn.prepareStatement("select content from javatest where name= ? for update");
      pstmt.setString(1,"fankai");
      ResultSet rset = pstmt.executeQuery();
      if (rset.next()) blob = (BLOB) rset.getBlob(1);

      String fileName = "oraclejdbc.jar";
      File f = new File(fileName);
      FileInputStream fin = new FileInputStream(f);
      System.out.println("file size = " + fin.available());

      pstmt = conn.prepareStatement("update javatest set content=? where name=?");

      OutputStream out = blob.getBinaryOutputStream();

      int count = -1, total = 0;
      byte[] data = new byte[(int)fin.available()];
      fin.read(data);
      out.write(data);
      /*
      byte[] data = new byte[blob.getBufferSize()];  另一种实现方法,节省内存
      while ((count = fin.read(data)) != -1) {
        total += count;
        out.write(data, 0, count);
      }
      */

      fin.close();
      out.close();

      pstmt.setBlob(1,blob);
      pstmt.setString(2,"fankai");

      pstmt.executeUpdate();
      pstmt.close();

      conn.commit();
      conn.close();
    } catch (SQLException e) {
      System.err.println(e.getMessage());
      e.printStackTrace();
    } catch (IOException e) {
      System.err.println(e.getMessage());
    }
  }

}
    
<p>

robbin
2003-09-15 19:12
上面是用JDBC写的demo,下面再来一个Hibernate写的demo,相比较之下,简单很多了:

      sf = HibernateSessionFactory.getSessionFactory();
      s = sf.openSession();  
      tx = s.beginTransaction();
      c = new Cat();
      c.setName("Robbin");
      c.setImage(Hibernate.createBlob(buffer));
      s.save(c);
      s.flush();
      s.refresh(c, LockMode.UPGRADE);    
      BLOB blob = (BLOB) c.getImage();      
      OutputStream out = blob.getBinaryOutputStream();   
      String fileName = "ojdbc14.jar";
      File f = new File(fileName);
      FileInputStream fin = new FileInputStream(f);   
      int count = -1, total = 0;
      byte[] data = new byte[(int)fin.available()];
      fin.read(data);
      out.write(data);      
      fin.close();
      out.close();
      s.flush();
      tx.commit();
<p>

猜你喜欢
3Go 1 2 3 下一页