2009-11-20 43 views
6

Tôi đang đặt và hình ảnh vào cơ sở dữ liệu, có thể là cơ sở dữ liệu MYSQL (Máy chủ) hoặc cơ sở dữ liệu SQLITE (máy tính bảng trên đường). Ứng dụng Java đồng bộ với máy chủ hàng ngày, tải lên dữ liệu mới và tải xuống bất kỳ dữ liệu mới nào. Phần đó hoạt động tốt. Tuy nhiên, yêu cầu là cho nó để có thể xử lý hình ảnh quá.Lỗi ngoại lệ Java - Sqlite prepareStatement.setBlob

Thay vì triển khai một hệ thống hoàn toàn mới dựa vào việc sao chép hình ảnh vào hệ thống tệp trên mỗi đầu, chúng tôi chọn sử dụng các đốm màu trong cơ sở dữ liệu. Không thực sự quan tâm đến câu trả lời mà nói không làm điều đó;) những gì tôi thực sự cần giúp đỡ là khi tôi cố gắng để viết blob tôi nhận được một ngoại lệ trong công văn.

Chúng tôi đang xây dựng các biểu mẫu đầu vào từ cơ sở dữ liệu, vì toàn bộ ứng dụng đang được sử dụng cho các mục đích khác nhau, phụ thuộc vào cơ sở dữ liệu. Biểu mẫu đầu vào cho phép bạn đính kèm hình ảnh vào bản ghi, chúng tôi lưu trữ dưới dạng chuỗi base64. Sau đó giải mã nó thành một byte [].

Chương trình thử nghiệm của tôi chuyển đổi qua lại giữa chuỗi chuỗi và byte (và cuối cùng là hình ảnh) không có vấn đề gì. Vì vậy, tôi khá thuyết phục rằng vấn đề là đặt Blob trong tuyên bố chuẩn bị, nhưng tôi có thể sai.

Ngoại lệ xảy ra sau khi nhấn nút Lưu.

Exception occurred during event dispatching: 
java.lang.AbstractMethodError: org.sqlite.PrepStmt.setBlob(ILjava/io/InputStream;J)V 
    at tabletapp.database.DB.prepareStatement(DB.java:641) 
    at tabletapp.database.DB.save(DB.java:743) 
    at tabletapp.FormPanel.saveData(FormPanel.java:546) 

Khối mã vi phạm

public void prepareStatement(String table, String sql, LinkedHashMap<String, String> data) { 
    try { 
     String typeID = ""; 
     PreparedStatement ps = connection.prepareStatement(sql); 
     log.debug("Preparing SQL: " + sql.replace("\n", "")); 
     int parameterIndex = 1; 

     //for (String columnName : getColumnNames(table)) { 
     for (String columnName : data.keySet()) { 
      typeID = getColumnType(table, columnName); 

      if (data.containsKey(columnName)) { 
       String value = data.get(columnName); 
       if (value == null || "".equals(value)) { 
        //log.debug(columnName+":"+parameterIndex+" set to null"); 
        ps.setNull(parameterIndex, Types.NULL); 
       } else { 
        //log.debug(columnName+":"+parameterIndex+" set to "+value); 
        switch (getColumnTypeId(table, columnName)) { 
         case Types.VARCHAR: 
         case Types.CHAR: 
          ps.setString(parameterIndex, value); 
          break; 

         case Types.TIMESTAMP: 
          DateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
          java.util.Date timstamp = new java.util.Date(); 
          ps.setString(parameterIndex, timestampFormat.format(timstamp)); 
          break; 

         case Types.DATE: 
          DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 
          java.util.Date date = new java.util.Date(); 
          ps.setString(parameterIndex, dateFormat.format(date)); 
          break; 

         case Types.SMALLINT: 
         case Types.INTEGER: 
         case Types.NUMERIC: 
          ps.setInt(parameterIndex, new Integer(value)); 
          break; 

         case Types.FLOAT: 
          ps.setFloat(parameterIndex, new Float(value)); 
          break; 

         case Types.BLOB: 
          // convert string to byte array to blob 
          byte[] bData = null; 
          try { 
           bData = new BASE64Decoder().decodeBuffer(value); 
           log.info("I have Bytes[]"); 
          } 
          catch (Exception e){ 
           log.info("Something went Horribly, Horribly Wrong"); 
          } 

          // Note tried the follwowing 
          //Blob blob=connection.createBlob(); 
          // blob.setBytes(bData.length, bData); 
          // ps.setBlob(parameterIndex,blob); 

          ByteArrayInputStream bais = new ByteArrayInputStream(bData); 
          ps.setBlob(parameterIndex, bais,bData.length); 


          break; 

         case Types.BOOLEAN: 
         case Types.BIT: 
          //log.debug(table + "." + columnName + " (boolean) = " + value); 
          if ("1".equals(value) || "true".equals(value)) { 
           ps.setBoolean(parameterIndex, true); 
          } else { 
           ps.setBoolean(parameterIndex, false); 
          } 
          break; 
        } 
       } 
       parameterIndex++; 
      } 
     } 
     ps.executeUpdate(); 
     connection.commit(); 
    } catch (SQLException e) { 
     log.error("Error in sql: " + sql); 
     e.printStackTrace(); 
    } 

} 

Bất kỳ trợ giúp đánh giá rất cao.

Trả lời

0

Hãy thử sử dụng trường 'đếm' để lấy độ dài đối tượng ByteArrayInputStream của bạn, bais, thay vì độ dài của chuỗi đã giải mã của bạn.

+0

Không chắc chắn nếu điều đó có thể, đếm được bảo vệ bên trong ByteArrayInputStream, vì vậy làm thế nào tôi sẽ truy cập nó. Thứ hai tôi nghĩ rằng dòng chỉ có một byte trong nó bất cứ lúc nào? Tôi đang cố gắng để quấn đầu của tôi xung quanh quá trình thực sự, vì vậy tôi có thể cách ra khỏi cơ sở. – Peter

7

Theo a recent post Xerial group phương thức setBlob không được triển khai trong sqlite-jdbc. Đối với tôi, những đề xuất thay thế

preparedStatement.setBytes(idx, data)

làm việc tốt, nếu dữ liệu nhị phân của bạn là đủ nhỏ để nạp vào bộ nhớ như mảng byte.

+0

đã lưu tôi! tôi chỉ có 5 phút để giải quyết vấn đề và đây là vấn đề! –