2013-04-15 37 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; 
    } 
} 

非常感谢大家的帮助。

相关问题