A few Exceptions when working with SQLite Database

This code:

public void foo() { new Thread() { @Override public void run() { ShaufelDatabaseHelper dbHelper = ShaufelDatabaseHelper.getInstance(parentActivity); SQLiteDatabase connection = null; Cursor queryData = null; final String[] values = new String[8]; try{ connection = dbHelper.getReadableDatabase(); queryData = connection.rawQuery( // line 132 "SELECT name, firstname, section, row, gravenr, type, workorder, comment "+ "FROM orders, graves "+ "WHERE orders.id=? AND graves.id=orders.id" , new String[] {orderID}); queryData.moveToFirst(); // line 138 // ... } catch(Throwable t) { // ... } }.start(); } 

gives me these Exceptions:

 10-29 15:19:55.103: E/AndroidRuntime(23102): FATAL EXCEPTION: Thread-1387 10-29 15:19:55.103: E/AndroidRuntime(23102): java.lang.IllegalMonitorStateException 10-29 15:19:55.103: E/AndroidRuntime(23102): at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:126) 10-29 15:19:55.103: E/AndroidRuntime(23102): at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1239) 10-29 15:19:55.103: E/AndroidRuntime(23102): at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:431) 10-29 15:19:55.103: E/AndroidRuntime(23102): at android.database.sqlite.SQLiteDatabase.unlock(SQLiteDatabase.java:487) 10-29 15:19:55.103: E/AndroidRuntime(23102): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:62) 10-29 15:19:55.103: E/AndroidRuntime(23102): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1564) 10-29 15:19:55.103: E/AndroidRuntime(23102): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1538) 10-29 15:19:55.103: E/AndroidRuntime(23102): at de.l_one.app.shaufel.OrderDetailView$3.run(OrderDetailView.java:132) 10-29 15:21:07.953: E/SQLiteQuery(23133): exception: library routine called out of sequence; query: SELECT name, firstname, section, row, gravenr, type, workorder, comment FROM orders, graves WHERE orders.id=? AND graves.id=orders.id 10-29 15:21:07.953: E/SQL order detail(23133): android.database.sqlite.SQLiteMisuseException: library routine called out of sequence 10-29 15:21:07.953: E/SQL order detail(23133): android.database.sqlite.SQLiteMisuseException: library routine called out of sequence 10-29 15:21:07.953: E/SQL order detail(23133): at android.database.sqlite.SQLiteQuery.nativeFillWindow(Native Method) 10-29 15:21:07.953: E/SQL order detail(23133): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:86) 10-29 15:21:07.953: E/SQL order detail(23133): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:164) 10-29 15:21:07.953: E/SQL order detail(23133): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:156) 10-29 15:21:07.953: E/SQL order detail(23133): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:161) 10-29 15:21:07.953: E/SQL order detail(23133): at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:201) 10-29 15:21:07.953: E/SQL order detail(23133): at de.l_one.app.shaufel.OrderDetailView$3.run(OrderDetailView.java:138) 10-29 15:22:52.983: E/AndroidRuntime(23133): FATAL EXCEPTION: Thread-1411 10-29 15:22:52.983: E/AndroidRuntime(23133): java.lang.IllegalStateException: database /data/data/de.l_one.app.shaufel/databases/poidatabase (conn# 0) already closed 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2082) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:58) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:127) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:94) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:53) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1564) 10-29 15:22:52.983: E/AndroidRuntime(23133): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1538) 10-29 15:22:52.983: E/AndroidRuntime(23133): at de.l_one.app.shaufel.OrderDetailView$3.run(OrderDetailView.java:132) 

They are not thrown out in one pass, but rather (which seems) randomly. There is no template when an exception is thrown, sometimes an exception is not thrown at all.
I use the same approach everywhere in my application and it works without a single problem. I don't have the least clue where the IllegalStateException comes IllegalStateException , because the database is not closed, at least not by me. (according to some answers to SO, which is fine, and in some cases it is even preferable to close your dbs manually).

Code Notes:
ShaufelDatabaseHelper is a Singleton that extends SQLiteOpenHelper . It is used in various activities that work in general, this is apparently the only exception.

I just checked this on the second device where no exception was thrown and everything works.
The device that throws exceptions is the lenovo thinkpad running Android 4.0.3.
The one that works with Outout Exceptions is the HTC Sensation Z710e running Android 2.3.4.

Does anyone have an idea what can do this?

E: I don't know if this helps, but it is logged before SQLiteMisuseException :

 10-29 16:07:46.530: I/SqliteDatabaseCpp(23728): sqlite returned: error code = 21, msg = API called with NULL prepared statement, db=/data/data/de.l_one.app.shaufel/databases/poidatabase 10-29 16:07:46.530: I/SqliteDatabaseCpp(23728): sqlite returned: error code = 21, msg = misuse at line 58929 of [8609a15dfa], db=/data/data/de.l_one.app.shaufel/databases/poidatabase 10-29 16:07:46.530: I/SqliteDatabaseCpp(23728): sqlite returned: error code = 21, msg = API call with invalid database connection pointer, db=/data/data/de.l_one.app.shaufel/databases/poidatabase 10-29 16:07:46.530: I/SqliteDatabaseCpp(23728): sqlite returned: error code = 21, msg = misuse at line 106340 of [8609a15dfa], db=/data/data/de.l_one.app.shaufel/databases/poidatabase 10-29 16:07:46.530: I/SqliteDatabaseCpp(23728): sqlite returned: error code = 21, msg = API call with invalid database connection pointer, db=/data/data/de.l_one.app.shaufel/databases/poidatabase 10-29 16:07:46.530: I/SqliteDatabaseCpp(23728): sqlite returned: error code = 21, msg = misuse at line 106271 of [8609a15dfa], db=/data/data/de.l_one.app.shaufel/databases/poidatabase 
+6
source share
1 answer

Cause

if any other case closed the database only between your call to getReadableDatabase() and rawQuery() or while rawQuery() is rawQuery() you will get this exception. this is because your SQLiteOpenHelper is singleton (and it should be), which means that if some other thread closed the database, one internal mDatabase member that maintains the connection to the database will be closed.

My advice:

implement your own close() method for your SQLiteOpenHelper derivative. in your implementation, check the number of open connections links before it is actually closed (call SQLiteOpenHelper.close() ).

 private int openedConnections = 0; //... public synchronized SQLiteDatabase getReadableDatabase() { openedConnections++; getReadableDatabase(); } public synchronized void close() { openedConnections--; if (openedConnections == 0) { close(); } } 

Let me know if this worked! :)

+10
source

All Articles