2016-07-31 2 views
0

Ich versuche, ein Objekt in eine Datenbank als ein Blob zu schreiben, aber ich bekomme java.sql.SQLException: [SQLITE_CONSTRAINT] Abort due to constraint violation (NOT NULL constraint failed: table_name.blob).Schreibe Objekt als Blob über BinaryStream in Java SQLite Update - NOT NULL Constraint Verletzung

Anfangs habe ich versucht, das Blob als SerialBlob zu schaffen und es auf einem PreparedStatement mit setBlob Einstellung, aber ich habe java.sql.SQLException: not implemented by SQLite JDBC driver. So habe ich, geleitet von this answer, versucht, einen inputStream für das Objekt zu erstellen und diesen als binären Stream festzulegen.

Ich weiß nicht, warum die Datenbank glaubt, dass die Einschränkung verletzt wird - in den folgenden Tests testStreamContentNotNull überschreitet, aber testDatabaseWrite löst die zuvor genannten SQLException.

import static org.assertj.core.api.Assertions.assertThat; 
import static org.junit.Assert.fail; 

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.Statement; 

import org.junit.Test; 

public class StackOverflowTest { 

    private static final String testStringToBeWrittenAsBlob = "abcdef"; 

    @Test 
    public void testStreamContentNotNull() { 
     try { 
      try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { 
       try (ObjectOutputStream oos = new ObjectOutputStream(bos)) { 
        oos.writeObject(testStringToBeWrittenAsBlob); 
        oos.flush(); 
        oos.close(); 
        try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray())) { 
         try (ObjectInputStream ois = new ObjectInputStream(bis)) { 
          assertThat((String)ois.readObject()).isEqualTo(testStringToBeWrittenAsBlob); 
         } 
        } 
       } 
      } 
     } catch (Exception e) { 
      fail(); 
     } 
    } 

    @Test 
    public void testDatabaseWrite() { 
     Connection c = null; 
     Statement stmt = null; 
     String sql = null; 

     try { 
      // Initialize the connection 
      Class.forName("org.sqlite.JDBC"); 
      c = DriverManager.getConnection("jdbc:sqlite::memory:"); 
      c.setAutoCommit(false); 

      // Create the table 
      stmt = c.createStatement(); 
      sql = "CREATE TABLE table_name " + 
        "(id INT PRIMARY KEY NOT NULL," + 
        "blob BLOB NOT NULL)"; 
      stmt.executeUpdate(sql); 
      c.commit(); 
      stmt.close(); 

      // Table has been created - now write to it 

      sql = "INSERT INTO table_name (id, blob) VALUES (?, ?)"; 
      PreparedStatement p_stmt = c.prepareStatement(sql); 
      try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) { 
       try(ObjectOutputStream oos = new ObjectOutputStream(bos)) { 
        oos.writeObject(testStringToBeWrittenAsBlob); 
        oos.flush(); 
        oos.close(); 
        try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray())) { 
         try (ObjectInputStream ois = new ObjectInputStream(bis)) { 
          p_stmt.setString(1, "test-id"); 
          p_stmt.setBinaryStream(2, ois); 
          p_stmt.execute(); // <--- This is where the exception is thrown 
          c.commit(); 
         } 
        } 

       } 
      } 


      c.close(); 


     } catch (Exception e) { 
      fail(); 
     } 
    } 
} 

Antwort

0

Für alle, die diese Frage findet, dank this post bekam ich es von der ByteArrayOutputStream::toBytes nur durch das Lesen zu arbeiten - also der folgende Test bestanden:

@Test 
public void testDatabaseWriteAsBytes() { 
    Connection c = null; 
    Statement stmt = null; 
    String sql = null; 

    try { 
     // Initialize the connection 
     Class.forName("org.sqlite.JDBC"); 
     c = DriverManager.getConnection("jdbc:sqlite::memory:"); 
     c.setAutoCommit(false); 

     // Create the table 
     stmt = c.createStatement(); 
     sql = "CREATE TABLE table_name " + 
       "(id INT PRIMARY KEY NOT NULL," + 
       "blob BLOB NOT NULL)"; 
     stmt.executeUpdate(sql); 
     c.commit(); 
     stmt.close(); 

     // Table has been created - now write to it 

     sql = "INSERT INTO table_name (id, blob) VALUES (?, ?)"; 
     PreparedStatement p_stmt = c.prepareStatement(sql); 
     try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) { 
      try(ObjectOutputStream oos = new ObjectOutputStream(bos)) { 
       oos.writeObject(testStringToBeWrittenAsBlob); 
       oos.flush(); 
       oos.close(); 

       p_stmt.setString(1, "test-id"); 
       p_stmt.setBytes(2, bos.toByteArray()); 
       p_stmt.execute(); // <--- No exception here now! 
       c.commit(); 
      } 
     } 

     String selectSql = "SELECT blob FROM table_name WHERE id='test-id'"; 
     Statement selectStatement = c.createStatement(); 
     ResultSet resultSet = selectStatement.executeQuery(selectSql); 
     if (resultSet.next()) { 
      try (ObjectInputStream ois = new ObjectInputStream(resultSet.getBinaryStream(1))) { 
       assertThat((String)ois.readObject()).isEqualTo(testStringToBeWrittenAsBlob); 
      } 
     } else { 
      fail("Nothing in result set"); 
     } 

     c.close(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
     fail(); 
    } 
} 

aber ich halte diese Frage offen weil ich immer noch nicht weiß warum dies in erster Linie gescheitert.

Verwandte Themen