1

I tried to save an object into sqlite, and the class of the object has implemented Serializable. But there is always an error:

 android.database.sqlite.SQLiteException: unrecognized token:
 "[Ljava.lang.Object;@277c81d9" (code 1): , while compiling: insert
 into mClass(classData) values(?)[Ljava.lang.Object;@277c81d9

Here is my code:

 public boolean add(ReturnInfo ri) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        db = dh.getWritableDatabase();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(ri);
        oos.flush();
        byte[] data = bos.toByteArray();
        bos.close();
        oos.close();
        db.execSQL("insert into mClass(classData) values(?)" + new Object[]{data});
        db.close();
        Log.e("db", "insert succeeded");
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("db", "insert failed");
        return false;
    }

The database has been created successfully, I have no idea where went wrong.

Ralf Rafael Frix
  • 1,393
  • 3
  • 21
  • 31
Zion Q
  • 95
  • 9
  • Sure its possible, sure there is no Syntax error? (SQLSyntax) – Luftbaum Aug 06 '16 at 08:21
  • 1
    You seem to expect string concatenation to replace the parameter value placeholder. Your SQL query is `"insert into mClass(classData) values(?)[Ljava.lang.Object;@277c81d9"`, which isn't valid SQL. Did you want to write `db.execSQL("insert into mClass(classData) values(?)", data)`? But my guess is that you need to use `compileStatement()` and `bindBlob()`. – dhke Aug 06 '16 at 08:24
  • Related: [how to store Image as blob in Sqlite & how to retrieve it?](https://stackoverflow.com/questions/7331310/how-to-store-image-as-blob-in-sqlite-how-to-retrieve-it) – dhke Aug 06 '16 at 08:26
  • @dhke Thank you so much, I used compileStatement() and bindBlob() then problem was solved. And also I finally found out that I have made Syntax error.I should use "," instead of "+"..... – Zion Q Aug 06 '16 at 08:59

1 Answers1

1

The issue is that you use prepared statements in a wrong way.

db.execSQL("insert into mClass(classData) values(?)" + new Object[]{data});

Here you generate inappropriate SQL statement because you just add an object to the end of the string and end up with something like this:

"insert into mClass(classData) values(?)[Ljava.lang.Object;@277c81d9"

which is not an SQL statement.

To use prepared statements you need write the following:

SQLiteStatement stmt = 
    db.compileStatement("insert into mClass(classData) values(?)");
stmt.bindString(1, data);
stmt.execute()

Also, look at this question to get a better understanding of prepared statements in android.

Community
  • 1
  • 1
Arkadii Berezkin
  • 248
  • 1
  • 11
  • No, OP clearly doesn't want a stringified representation of an object array in the database. You need `bindBlob()`. – dhke Aug 06 '16 at 08:50
  • @dhke yeah, you're right and that's why I leave a link to the post about object serialization. Maybe I need to edit `toString()` part to make it clearer? – Arkadii Berezkin Aug 06 '16 at 09:00
  • Thank you. Your answer helps me a lot ! – Zion Q Aug 06 '16 at 09:01
  • 1
    @aberezkin The object is already serialized into a byte array. No need to make it a string, Sqlite stores binary data just fine. That's exactly what the `BLOB` datatype and `bindBlob()` are for. – dhke Aug 06 '16 at 09:04
  • @dhke Oh, now I get it. It's my first answer on Stack Overflow, actually, and it's great how you can learn something new even by answering questions. Thank you for correction. Edited the answer. – Arkadii Berezkin Aug 06 '16 at 09:43