1

Here is my code:

public class ResultDbHandler extends DatabaseHandler {
    private final String TABLE_RESULTS = "results";

    private final String RESULT_ORDER = "order";
    private final String RESULT_PROFILE = "resultProfileId";
    private final String RESULT_FVC = "fvc";
    private final String RESULT_FEV1 = "fev1";
    private final String RESULT_PEV = "pev";
    private final String RESULT_TIME = "time";


    public ResultDbHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        final String query = "CREATE TABLE " + TABLE_RESULTS + " ("
                + RESULT_ORDER + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + RESULT_PROFILE + " TEXT, "
                + RESULT_FVC + " REAL, "
                + RESULT_FEV1 + " REAL, "
                + RESULT_PEV + " REAL, "
                + RESULT_TIME + " TEXT, "
                + "FOREIGN KEY(" + RESULT_PROFILE + ") REFERENCES "
                + ProfileDbHandler.TABLE_PROFILES + "(" + ProfileDbHandler.PROFILE_ID + "))";
        db.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_RESULTS);
        onCreate(db);
    }

    @Override
    public boolean isDbExist() {
        return countRecord() > 0;
    }

    @Override
    public int countRecord() {
        SQLiteDatabase db = getReadableDatabase();
        final String query = "SELECT count(*) FROM " + TABLE_RESULTS;
        Cursor cursor = db.rawQuery(query, null);
        int result = cursor.moveToFirst() ? cursor.getInt(0) : 0;
        cursor.close();
        db.close();
        return result;
    }

Anyway, DatabaseHandler directly extends SQLiteOpenHelper. Then, I simply call isDbExist() right after initializing dbHandler object which is like

...
dbHandler = new ResultDbHandler(activity);
dbHandler.isDbExist();
...

Somehow, the app crashed and the logcat said:

09-09 22:34:58.904 4789-4789/? E/SQLiteLog: (1) no such table: results
09-09 22:34:58.907 4789-4789/? D/AndroidRuntime: Shutting down VM
09-09 22:34:58.910 4789-4789/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 Process: com.kahl.silir, PID: 4789
                                                 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kahl.silir/com.kahl.silir.main.history.MeasurementResultActivity}: android.database.sqlite.SQLiteException: no such table: results (code 1): , while compiling: SELECT count(*) FROM results
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2464)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2526)
                                                     at android.app.ActivityThread.access$800(ActivityThread.java:169)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
                                                     at android.os.Handler.dispatchMessage(Handler.java:111)
                                                     at android.os.Looper.loop(Looper.java:194)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5549)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:372)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
                                                  Caused by: android.database.sqlite.SQLiteException: no such table: results (code 1): , while compiling: SELECT count(*) FROM results
                                                     at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                     at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:898)
                                                     at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:509)
                                                     at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                                                     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                                                     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1346)
                                                     at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1285)
                                                     at com.kahl.silir.databasehandler.ResultDbHandler.countRecord(ResultDbHandler.java:64)
                                                     at com.kahl.silir.databasehandler.ResultDbHandler.isDbExist(ResultDbHandler.java:57)
                                                     at com.kahl.silir.main.history.MeasurementResultActivity.onCreate(MeasurementResultActivity.java:54)
                                                     at android.app.Activity.performCreate(Activity.java:5977)
                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2526) 
                                                     at android.app.ActivityThread.access$800(ActivityThread.java:169) 
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 
                                                     at android.os.Handler.dispatchMessage(Handler.java:111) 
                                                     at android.os.Looper.loop(Looper.java:194) 
                                                     at android.app.ActivityThread.main(ActivityThread.java:5549) 
                                                     at java.lang.reflect.Method.invoke(Native Method) 
                                                     at java.lang.reflect.Method.invoke(Method.java:372) 
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964) 
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759) 

I have no idea why onCreate method from ResultDbHandler isn't called even though it said the table didn't exist. I've just done the same pattern in another activity using another direct child of DatabaseHandler. It works properly. Please kindly explain to me, why could this happen and how to fix it?

  • SQLiteOpenHelper does not care about tables, all it cares is database files and versioning of them. https://stackoverflow.com/questions/21881992/when-is-sqliteopenhelper-oncreate-onupgrade-run – laalto Sep 09 '17 at 16:00
  • so how can I create the table automatically when the constructor is called for the first time only? @laalto – Paskahlis Anjas Prabowo Sep 09 '17 at 16:04
  • It's likely you already have a database file with the same name and version, so `onCreate()` or `onUpgrade()` is not triggered. You can uninstall your app to get rid of that database file. – laalto Sep 09 '17 at 16:15
  • The code does not show what `DATABASE_NAME` etc. are but is it possible that you're sharing the same database file in more than one `SQLiteOpenHelper`? That would not work. – laalto Sep 09 '17 at 16:16
  • Good guess! I already have a database file with the same name and version. I got it, thanks for helping @laalto is there another alternative way to share the same database file? – Paskahlis Anjas Prabowo Sep 09 '17 at 16:27
  • Put all your code for the tables in the same database file under the same SQLiteOpenHelper class. – laalto Sep 09 '17 at 16:28

0 Answers0