2009-11-20 10 views
6

मैं डेटाबेस में रख रहा हूं और छवि डाल रहा हूं, यह या तो एक MYSQL डेटाबेस (सर्वर) या एक SQLITE डेटाबेस (सड़क पर एक टैबलेट पीसी) हो सकता है। जावा एप्लिकेशन दैनिक आधार पर सर्वर के साथ समन्वयित करता है, नया डेटा अपलोड करता है और कोई नया डेटा डाउनलोड करता है। वह हिस्सा अच्छी तरह से काम कर रहा है। हालांकि, इसके लिए छवियों को भी संभालने में सक्षम होना आवश्यक है।जावा अपवाद त्रुटि - स्क्लाइट तैयारस्टेटमेंट.सेटब्लोब

एक पूरी नई प्रणाली को लागू करने के बजाय जो छवियों को प्रत्येक छोर पर फाइल सिस्टम पर कॉपी करने पर निर्भर करता है, हम डेटाबेस में ब्लॉब्स का उपयोग करने का विकल्प चुन रहे हैं। प्रतिक्रियाओं में वास्तव में दिलचस्पी नहीं है जो कहते हैं कि ऐसा नहीं करते हैं;) मुझे वास्तव में मदद की ज़रूरत है कि जब मैं ब्लॉब लिखने की कोशिश करता हूं तो मुझे प्रेषण में अपवाद मिलता है।

हम डेटाबेस से इनपुट फॉर्म बना रहे हैं, क्योंकि पूरे एप्लिकेशन का उपयोग विभिन्न उद्देश्यों के लिए किया जा रहा है, जो डेटाबेस पर निर्भर है। इनपुट फॉर्म आपको रिकॉर्ड में एक छवि संलग्न करने की अनुमति देता है, हम इसे बेस 64 स्ट्रिंग के रूप में स्टोर करते हैं। फिर इसे एक बाइट [] में डीकोड करें।

मेरा परीक्षण प्रोग्राम स्ट्रिंग और बाइट सरणी (और अंततः एक छवि) के बीच कोई समस्या नहीं बदलता है। तो मुझे काफी आश्वस्त है कि मुद्दा तैयार बयान में ब्लॉब स्थापित करने में है, लेकिन मैं गलत हो सकता था।

सहेजें बटन क्लिक होने के बाद अपवाद होता है।

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) 

अपमानजनक कोड ब्लॉक

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(); 
    } 

} 

किसी भी मदद की बहुत सराहना।

उत्तर

0

अपनी डीकोडेड स्ट्रिंग की लंबाई के बजाय, अपने ByteArrayInputStream ऑब्जेक्ट की लंबाई प्राप्त करने के लिए 'गिनती' फ़ील्ड का उपयोग करने का प्रयास करें।

+0

यह सुनिश्चित नहीं है कि यह संभव है, तो गिनती ByteArrayInputStream के अंदर सुरक्षित है, तो मैं इसे कैसे एक्सेस करूंगा। सेकेंडली मैंने सोचा कि धारा में किसी एक समय में केवल एक बाइट था? मैं वास्तव में प्रक्रिया के चारों ओर अपने सिर को लपेटने की कोशिश कर रहा हूं, इसलिए मैं आधार से बाहर निकल सकता हूं। – Peter

7

a recent post Xerial group के अनुसार विधि सेटब्लॉब sqlite-jdbc में लागू नहीं किया गया है। मेरे लिए, विकल्प प्रस्तावित

preparedStatement.setBytes(idx, data)

ठीक काम किया, यदि आपका बाइनरी डेटा काफी छोटा बाइट सरणी के रूप में स्मृति में लोड करने के लिए है।

+0

मुझे बचाया! मुझे समस्या को हल करने के लिए केवल 5 मिनट की तरह था और यह था! –

संबंधित मुद्दे