2013-04-15 41 views
7

有沒有人有一個想法,我在這裏做錯了什麼?我試圖插入一個blob(包含一個pdf,以防重要)到一個oracle數據庫以及一些額外的信息。我使用PreparedStatementNullPointerException在Oracle DB上執行PreparedStatement插入Blob時

代碼:

public void saveReportErgebnis(int reportId, Date erzeugung, int archiv, 
     Blob pdf, String kommentar) throws Exception { 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    byte[] tmp = new byte[(int) pdf.length()]; 
    if(kommentar == null){ 
     kommentar = ""; 
    } 

    SimpleDateFormat erstellungSdf = new SimpleDateFormat(
      "yyyy-MM-dd HH:mm:ss"); 

    try { 
    pdf.getBinaryStream().read(tmp); 

    oracle.sql.BLOB oracleBlob = new oracle.sql.BLOB((OracleConnection) getConnection(), tmp); 
    PreparedStatement prepStmt = getRTTDBHandler() 
      .createPreparedStatement(
        "INSERT INTO reportergebnis(report_id, erzeugung, archiv, pdf, kommentar) VALUES (?,?,?,?,?)"); 
    System.out.println("debug 2 oracle"); 
     prepStmt.setInt(1, reportId); 
     prepStmt.setString(2, formatDateString(erstellungSdf.format(erzeugung))); 
     prepStmt.setInt(3, archiv); 
     prepStmt.setBlob(4, oracleBlob); 
     prepStmt.setString(5, kommentar); 
     prepStmt.execute(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     loghandler.error(e.toString()); 
     throw e; 
    } 

} 

(formatCode是把在右邊的表格日期,例如一回:
日期TO_DATE('2013年4月15日9時34分38秒」, 'YYYY-MM-DD HH24:MI:SS')

當PrepStatement執行我得到以下例外:

{java.lang.ArrayIndexOutOfBoundsException 
     at java.lang.System.arraycopy(Native Method) 
     at oracle.jdbc.driver.DatumBinder.bind(OraclePreparedStatement.java:18279) 
     at oracle.jdbc.driver.OraclePreparedStatement.setupBindBuffers(OraclePreparedStatement.java:3137) 
     at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2355) 
     at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3579) 
     at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685) 
     at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1088) 
     at com.nundp.mc.modules.regressionsTest.db.OracleRTTDBHandler.saveReportErgebnis(OracleRTTDBHandler.java:963) 
     at com.nundp.mc.modules.regressionsTest.report.ReportController.executeReport(ReportController.java:237) 
     at org.apache.jsp.jsp.modules.Testszenario.ReportHandler_jsp._jspService(ReportHandler_jsp.java:156) 
     at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
     at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374) 
     at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342) 
     at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
     at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630) 
     at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:535) 
     at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:472) 
     at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968) 
     at org.apache.jsp.jsp.McFrame_jsp._jspService(McFrame_jsp.java:284) 
     at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
     at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374) 
     at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342) 
     at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) 
     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845) 
     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) 
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) 
     at java.lang.Thread.run(Thread.java:619)} 

我一個m使用Oracle數據庫10g版本10.2.0.3.0。 請幫忙!

+0

「OracleRTTDBHandler」文件的第963行是什麼? –

+0

prepStmt.execute(); – olkoza

+0

也許[this] [1]。 [1]:http://stackoverflow.com/questions/277744/jdbc-oracle-arrayindexoutofboundsexception 希望這有助於亞龍 –

回答

0

嘗試使用oracle.sql.BLOB上的* createTemporary(yourConnection,false,oracle.sql.BLOB.DURATION_CALL)*函數來創建實例。之後,只需使用setBytes(...)來設置其內容即可。

0

一句話:prepStmt.setDate(2, erzeugung);更簡單。

我本來期望簡單:

InputStream blobIS = pdf.getBinaryStream(); 
prepStmt.setBlob(4, blobIS, pdf.length()); 

... pdf.free(); 
1

在我的應用我用了一個File代替Blob爲方法輸入和所做的BLOB插入這樣:

public void insertBlob(String filedesc, File file) { 
    Connection con = DriverManager.getConnection(url, username, password); 

    InputStream input = new FileInputStream(file); 

    PreparedStatement pstmt = con.prepareStatement(
     "insert into schema.table values(?,?)"); 
    pstmt.setString(1, filedesc); 
    pstmt.setBinaryStream(2, input); 

    pstmt.execute(); 
} 

也許你需要一些try-catch,但我希望這會幫助你。

+0

+1。根據我的經驗,使用setBinaryStream()比任何替代方法都要好得多 –

0

我想你必須使用的setBlob()

  1. 檢查參數的數量在你的數據庫表
  2. 檢查BLOB的位置之前,做一些衛生檢查。

但是,我寧願建議您只在數據庫中存儲URl,而不是存儲文件的二進制數據。

0

對於未來的搜索,這是我解決了這個問題,一滴:

public void saveReportErgebnis(int reportId, Date erzeugung, int archiv, 
     Blob pdf, String kommentar) throws Exception { 

    byte[] tmp = new byte[(int) pdf.length()]; 
    if (kommentar == null) { 
     kommentar = ""; 
    } 

    try { 
     pdf.getBinaryStream().read(tmp); 
     PreparedStatement prepStmt = getRTTDBHandler() 
       .createPreparedStatement(
         "INSERT INTO reportergebnis(report_id, erzeugung, archiv, pdf, kommentar) VALUES (?,?,?,?,?)"); 
     prepStmt.setInt(1, reportId); 
     Timestamp ts = new Timestamp(erzeugung.getTime()); 
     prepStmt.setTimestamp(2, ts); 
     prepStmt.setInt(3, archiv); 
     prepStmt.setBytes(4, tmp); 
     prepStmt.setString(5, "'" + kommentar + "'"); 
     prepStmt.execute(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     loghandler.error(e.toString()); 
     throw e; 
    } 
} 

非常感謝大家的幫助。

相關問題