Android sqlite getdatabase called recursively
android, database, sqlite
Solution
Calling `getWritableDatabase()` when the database file doesn't exist causes the open helper `onCreate()` to be invoked.
The `db` passed to as an argument to `onCreate()` is the database being opened. You should use it for your initialization instead of calling `getWritableDatabase()` again as you do in your `insertPW()` and other methods. The `db == null || !db.isOpen()` condition doesn't help since you've just initialized the local `db` variable to `null`.
Problem
I have got a problem with my database. When the app start it should create the database with the tables if they not exist, but the app chrashes instantly after start. When i close the db after opening logcat tells me that "i want to open an already closed object" and when I do not close the database I have got the error "`getReadableDatabase called recursively`". I do not know what I should do. Sometimes it works but when I unistall the app and install them again the errors apear. The error without the close: ``` 02-20 11:50:06.980: E/AndroidRuntime(15375): FATAL EXCEPTION: main 02-20 11:50:06.980: E/AndroidRuntime(15375): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.vertretungsplan2/de.vertretungsplan2.Main}: java.lang.IllegalStateException: getDatabase called recursively 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.app.ActivityThread.access$600(ActivityThread.java:153) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.os.Handler.dispatchMessage(Handler.java:99) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.os.Looper.loop(Looper.java:137) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.app.ActivityThread.main(ActivityThread.java:5289) 02-20 11:50:06.980: E/AndroidRuntime(15375): at java.lang.reflect.Method.invokeNative(Native Method) 02-20 11:50:06.980: E/AndroidRuntime(15375): at java.lang.reflect.Method.invoke(Method.java:525) 02-20 11:50:06.980: E/AndroidRuntime(15375): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) 02-20 11:50:06.980: E/AndroidRuntime(15375): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555) 02-20 11:50:06.980: E/AndroidRuntime(15375): at dalvik.system.NativeStart.main(Native Method) 02-20 11:50:06.980: E/AndroidRuntime(15375): Caused by: java.lang.IllegalStateException: getDatabase called recursively 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:204) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164) 02-20 11:50:06.980: E/AndroidRuntime(15375): at de.vertretungsplan2.helper.DBHandler.insertPW(DBHandler.java:89) 02-20 11:50:06.980: E/AndroidRuntime(15375): at de.vertretungsplan2.helper.DBHandler.onCreate(DBHandler.java:46) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164) 02-20 11:50:06.980: E/AndroidRuntime(15375): at de.vertretungsplan2.Main.onCreate(Main.java:42) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.app.Activity.performCreate(Activity.java:5133) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 02-20 11:50:06.980: E/AndroidRuntime(15375): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293) 02-20 11:50:06.980: E/AndroidRuntime(15375): ... 11 more ``` The error with close: ``` 02-20 11:57:47.880: E/AndroidRuntime(15853): FATAL EXCEPTION: main 02-20 11:57:47.880: E/AndroidRuntime(15853): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.vertretungsplan2/de.vertretungsplan2.Main}: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/de.vertretungsplan2/databases/settings 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.app.ActivityThread.access$600(ActivityThread.java:153) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.os.Handler.dispatchMessage(Handler.java:99) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.os.Looper.loop(Looper.java:137) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.app.ActivityThread.main(ActivityThread.java:5289) 02-20 11:57:47.880: E/AndroidRuntime(15853): at java.lang.reflect.Method.invokeNative(Native Method) 02-20 11:57:47.880: E/AndroidRuntime(15853): at java.lang.reflect.Method.invoke(Method.java:525) 02-20 11:57:47.880: E/AndroidRuntime(15853): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) 02-20 11:57:47.880: E/AndroidRuntime(15853): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555) 02-20 11:57:47.880: E/AndroidRuntime(15853): at dalvik.system.NativeStart.main(Native Method) 02-20 11:57:47.880: E/AndroidRuntime(15853): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/de.vertretungsplan2/databases/settings 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:520) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:263) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164) 02-20 11:57:47.880: E/AndroidRuntime(15853): at de.vertretungsplan2.Main.onCreate(Main.java:42) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.app.Activity.performCreate(Activity.java:5133) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 02-20 11:57:47.880: E/AndroidRuntime(15853): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293) 02-20 11:57:47.880: E/AndroidRuntime(15853): ... 11 more ``` This is my DBHandler: ``` package de.vertretungsplan2.helper; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DBHandler extends SQLiteOpenHelper { private static final String TAG = "DBHandler"; //Attributes of Database private static final int DATABASE_VERSION = 1; private static final String DATABASE_NAME = "settings"; //Attributes of table "PASSWORD" private static final String TABLE_NAME_PW = "password"; private static final String PASSWORD_ID ="id"; private static final String PASSWORD_NAME = "password"; //Attributes of table "KURS" private static final String TABLE_NAME_KURS = "kurs"; private static final String KURS_ID = "id"; private static final String KURS_NAME ="kurs"; //Operations private static final String DROP_PW_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME_PW; private static final String DROP_KURS_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME_KURS; //Attributes of DBHandler public DBHandler(Context context){ super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { Log.i(TAG,"db aktion start, DBHandler-onCreate"); /* if(db == null || !db.isOpen()) { db = getWritableDatabase(); }*/ createTables(db); insertPW("-1"); insertKurs("-1"); db.close(); Log.i(TAG,"db aktion stop, DBHandler-onCreate"); } private void createTables(SQLiteDatabase db){ Log.i(TAG,"db aktion start, DBHandler-createTables"); String CREATE_PW_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME_PW +" (" + PASSWORD_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + PASSWORD_NAME + " TEXT);"; String CREATE_KURS_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME_KURS +" (" + KURS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KURS_NAME + " TEXT);"; if(db == null || !db.isOpen()) { db = getWritableDatabase(); } db.execSQL(CREATE_PW_TABLE); Log.i(TAG,"db aktion start, nach PW Table erzeugen"); db.execSQL(CREATE_KURS_TABLE); Log.i(TAG,"db aktion start, nach Kurs Table erzeugen"); db.close(); Log.i(TAG,"db aktion stop, DBHandler-createTables"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.i(TAG,"db aktion start, DBHandler-onUpgrade"); Log.w(TAG,"Upgrade der Datenbank von Version " + oldVersion + " zu " + newVersion + "; alle Daten werden gelöscht"); db.execSQL(DROP_PW_TABLE); Log.i(TAG,"db aktion start, OnUpgrade nach Drop PW Table"); db.execSQL(DROP_KURS_TABLE); Log.i(TAG,"db aktion start, OnUpgrade nach Drop kurs Table"); db.close(); Log.i(TAG,"db aktion start, OnUpgrade nach close db"); onCreate(db); Log.i(TAG,"db aktion stop, DBHandler-onUpgrade"); } public void insertPW(String PW){ Log.i(TAG,"db aktion start, DBHandler-insertPW"); long rowId = -1; try{ SQLiteDatabase db = null; if(db == null || !db.isOpen()) { db = getWritableDatabase(); } ContentValues values = new ContentValues(); values.put(PASSWORD_NAME, PW); rowId = db.insert(TABLE_NAME_PW, null, values); db.close(); }catch (SQLiteException e){ Log.e(TAG,"insert()",e); }finally{ Log.d(TAG, "insert(): rowId=" + rowId); Log.i(TAG,"db aktion stop, DBHandler-insertPW"); } } public void insertKurs(String Kurs){ Log.i(TAG,"db aktion start, DBHandler-insertKurs"); long rowId = -1; try{ SQLiteDatabase db = null; if(db == null || !db.isOpen()) { db = getWritableDatabase(); } ContentValues values = new ContentValues(); values.put(KURS_NAME, Kurs); rowId = db.insert(TABLE_NAME_KURS, null, values); db.close(); }catch (SQLiteException e){ Log.e(TAG,"insert()",e); }finally{ Log.d(TAG, "insert(): rowId=" + rowId); Log.i(TAG,"db aktion stop, DBHandler-insertKurs"); } } public String getPW(){ Log.i(TAG,"db aktion start, DBHandler-getPW"); SQLiteDatabase db = null; if(db == null || !db.isOpen()) { db = getReadableDatabase(); } Cursor cursor = db.query(TABLE_NAME_PW, new String[] {PASSWORD_ID, PASSWORD_NAME},null,null,null,null,null); for(int i=0; i<cursor.getCount();i++){ cursor.moveToNext(); } Log.i(TAG,"db aktion stop, DBHandler-getPW"); db.close(); return cursor.getString(1); } public String getKurs(){ Log.i(TAG,"db aktion start, DBHandler-getKurs"); SQLiteDatabase db = null; if(db == null || !db.isOpen()) { db = getReadableDatabase(); } Cursor cursor = db.query(TABLE_NAME_KURS, new String[] {KURS_ID, KURS_NAME},null,null,null,null, null); for(int i=0; i<cursor.getCount();i++){ cursor.moveToNext(); } db.close(); Log.i(TAG,"db aktion stop, DBHandler-getKurs"); return cursor.getString(1); } public int getPWCount(){ Log.i(TAG,"db aktion start, DBHandler-getPWCount"); String query = "SELECT * FROM " + TABLE_NAME_PW; SQLiteDatabase db = null; if(db == null || !db.isOpen()) { db = getReadableDatabase(); } Cursor cursor = db.rawQuery(query,null); Log.i(TAG,"db aktion stop, DBHandler-getPWCount"); db.close(); return cursor.getCount(); } public int getKursCount(){ Log.i(TAG,"db aktion start, DBHandler-getKursCount"); String query = "SELECT * FROM " + TABLE_NAME_KURS; SQLiteDatabase db = null; if(db == null || !db.isOpen()) { db = getReadableDatabase(); } Cursor cursor = db.rawQuery(query,null); Log.i(TAG,"db aktion stop, DBHandler-getKursCount"); db.close(); return cursor.getCount(); } } ``` I used this Logs to find out where the error apears but it does not help me. Thank you for help.