'Room Database Table is still empty after inserting new data

I've just finished this tutorial for my app.

But my problem is that even after I insert the data, my database is still empty. I checked that by viewing it in a Database browser and there are no records in it. Any help would be highly appreciated. If you need any more info let me know.

Dao object class:

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertRecord(LocationDetails Details);

my entity class:

@Entity(tableName = "location")
public class LocationDetails {

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @PrimaryKey(autoGenerate = true)
    private int id;
    private String jsonObjectString;
    private double latitude;
    private double longitude;
    private String locationType;

    public String getLocationType() {
        return locationType;
    }

    public void setLocationType(String locationType) {
        this.locationType = locationType;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public String getJsonObjectString() {
        return jsonObjectString;
    }

    public void setJsonObjectString(String jsonObjectString) {
        this.jsonObjectString = jsonObjectString;
    }

    public String toString() {
        return "Lat: " + latitude + ", Long: " + longitude;
    }
}

This is my database controller class which my ViewModels use to interact with the DB.

public class DatabaseController {

    private String TAG = getClass().getSimpleName();

    private static DatabaseController sInstance;
    private LiveData<List<LocationDetails>> mListOfLocations;
    private Database mDatabase;

    private DatabaseController(Context context) {
        mDatabase = Database.getDatabase(context);
    }

    public static DatabaseController getInstance() {
        return sInstance;
    }

    public static void initInstance(Context context) {
        sInstance = new DatabaseController(context);
    }

    public void addLocationRecord(LocationDetails locationDetails) {
        new insertAsyncTask(mDatabase).execute(locationDetails);
        Log.d(TAG, "Location Record Added Successfully");
    }

    private static class insertAsyncTask extends AsyncTask<LocationDetails, Void, Void> {

        private Database database;

        insertAsyncTask(Database database) {
            this.database = database;
        }

        @Override
        protected Void doInBackground(LocationDetails... databases) {
            database.mMyDao().insertRecord(databases[0]);
            return null;
        }
    }
}

I've added breakpoints at every step and checked. The entire code runs without any exception or error but still there is no record added in my Database.

And the question answered here is the same but his solution was different so not a duplicate. Room Database Table is still empty after inserting data

I receive these logs the first time:

2018-10-26 18:18:41.329 27827-27827/genesis.com.getlocation D/DatabaseController: Location Record Added Successfully
2018-10-26 18:18:41.345 27827-27876/genesis.com.getlocation D/Surface: Surface::disconnect(this=0x990a1f00,api=1)
2018-10-26 18:18:41.346 27827-27944/genesis.com.getlocation W/SQLiteConnection: Could not change the database journal as DB was busy. Proceeding...
2018-10-26 18:18:41.347 27827-27876/genesis.com.getlocation D/GraphicBuffer: unregister, handle(0xaaf92040) (w:848 h:1264 s:848 f:0x1 u:0x000b00)
2018-10-26 18:18:41.347 27827-27876/genesis.com.getlocation D/GraphicBuffer: unregister, handle(0xaaf92400) (w:848 h:1264 s:848 f:0x1 u:0x000b00)
2018-10-26 18:18:41.347 27827-27876/genesis.com.getlocation D/GraphicBuffer: unregister, handle(0xaaf924c0) (w:848 h:1264 s:848 f:0x1 u:0x000b00)
2018-10-26 18:18:41.347 27827-27876/genesis.com.getlocation D/Surface: Surface::disconnect(this=0x990a1f00,api=1)
2018-10-26 18:18:41.362 27827-27944/genesis.com.getlocation W/SQLiteConnection: Could not change the database journal as DB was busy. Proceeding...
2018-10-26 18:18:41.369 27827-27944/genesis.com.getlocation D/SQLiteDatabase: beginTransaction()
2018-10-26 18:18:41.372 27827-27944/genesis.com.getlocation D/SQLiteDatabase: endTransaction()
2018-10-26 18:18:41.374 27827-27827/genesis.com.getlocation D/WindowClient: Remove from mViews: DecorView@74e9112[], this = android.view.WindowManagerGlobal@fbcfdce
2018-10-26 18:18:41.377 27827-27827/genesis.com.getlocation V/InputMethodManager: onWindowFocus: null softInputMode=32 first=false flags=#81810100
2018-10-26 18:18:41.380 27827-27944/genesis.com.getlocation D/SQLiteDatabase: beginTransaction()
2018-10-26 18:18:41.384 27827-27944/genesis.com.getlocation D/SQLiteDatabase: endTransaction()
2018-10-26 18:18:41.394 27827-27873/genesis.com.getlocation I/BufferQueueProducer: [SurfaceTexture-0-27827-0](this:0xa8461000,id:0,api:1,p:27827,c:27827) queueBuffer: fps=0.67 dur=4486.29 max=3892.05 min=17.56
2018-10-26 18:18:41.403 27827-27945/genesis.com.getlocation D/SQLiteDatabase: beginTransaction()
2018-10-26 18:18:41.405 27827-27945/genesis.com.getlocation D/SQLiteDatabase: endTransaction()

I receive these logs afterwards always: (the difference is the Database is busy statement):

 2018-10-26 18:18:08.788 27080-27080/genesis.com.getlocation D/ConfirmDialogFragment: onDialogButtonClicked
2018-10-26 18:18:08.788 27080-27080/genesis.com.getlocation D/ConfirmDialogFragmentViewModel: RadioButton value is Desimus
2018-10-26 18:18:08.788 27080-27080/genesis.com.getlocation D/ConfirmDialogFragmentViewModel: Name of place is  Khan Plaza
2018-10-26 18:18:08.789 27080-27080/genesis.com.getlocation D/DatabaseController: Location Record Added Successfully
2018-10-26 18:18:08.791 27080-27775/genesis.com.getlocation D/SQLiteDatabase: beginTransaction()
2018-10-26 18:18:08.805 27080-27775/genesis.com.getlocation D/SQLiteDatabase: endTransaction()
2018-10-26 18:18:08.824 27080-27166/genesis.com.getlocation D/Surface: Surface::disconnect(this=0x94b83e00,api=1)
2018-10-26 18:18:08.825 27080-27166/genesis.com.getlocation D/GraphicBuffer: unregister, handle(0xa6043c40) (w:848 h:1264 s:848 f:0x1 u:0x000b00)
2018-10-26 18:18:08.826 27080-27166/genesis.com.getlocation D/GraphicBuffer: unregister, handle(0xa60425c0) (w:848 h:1264 s:848 f:0x1 u:0x000b00)
2018-10-26 18:18:08.826 27080-27166/genesis.com.getlocation D/GraphicBuffer: unregister, handle(0xa6042680) (w:848 h:1264 s:848 f:0x1 u:0x000b00)
2018-10-26 18:18:08.826 27080-27166/genesis.com.getlocation D/Surface: Surface::disconnect(this=0x94b83e00,api=1)
2018-10-26 18:18:08.829 27080-27602/genesis.com.getlocation D/SQLiteDatabase: beginTransaction()
2018-10-26 18:18:08.831 27080-27602/genesis.com.getlocation D/SQLiteDatabase: endTransaction()
2018-10-26 18:18:08.859 27080-27080/genesis.com.getlocation D/WindowClient: Remove from mViews: DecorView@3ad944e[], this = android.view.WindowManagerGlobal@40be950
2018-10-26 18:18:08.867 27080-27080/genesis.com.getlocation V/InputMethodManager: onWindowFocus: null softInputMode=32 first=false flags=#81810100
2018-10-26 18:18:08.879 27080-27235/genesis.com.getlocation I/BufferQueueProducer: [SurfaceTexture-0-27080-1](this:0xa8460000,id:1,api:1,p:27080,c:27080) queueBuffer: fps=0.44 dur=4554.45 max=4532.60 min=21.85
2018-10-26 18:18:08.893 27080-27235/genesis.com.getlocation I/BufferQueueProducer: [SurfaceTexture-0-27080-1](this:0xa8460000,id:1,api:1,p:27080,c:27080) queueBuffer: slot 0 is dropped, handle=0xaaf91800


Solution 1:[1]

Most likely you are not getting successful insert.

Make sure you are getting a primary ID back on insert Make sure you are doing the insert on a background thread. Make sure you are doing the retrieve on a background thread

Also if you made changes to the model after installing that will cause it to fail at touching the DB because the schema no longer matches the model variables.

So check your database create line of code, and make sure you have a handle for schema changes such as changing your model. Destructive fallback is fine, or uninstall and resinstall if no one is using it yet.

Solution 2:[2]

Check that your LocationDetails class implements Serializable. In your class extending RoomDatabase insert the class you want to add this way

 @Database(entities = {
        LocationDetails.class,
     },version = 1, exportSchema = false)

and make sure to update the version number each time you add/remove a class in your database. Also, I would recommend using the version 1.1.1-rc1 of room, which is more stable than 1.1.1 by adding this line in your gradle

 implementation 'android.arch.persistence.room:runtime:1.1.1-rc1'

Also, I would recommend calling your request in a Thread, on Android 6+ (maybe seven don't really recall) every AsyncTask of the devices share the same thread and wait there turn to execute the DoInBackground function and it can't take up to 5-10 sec sometimes to launch your task.

Solution 3:[3]

Another reason for me was that I was copying just the database file (the one that usually has .db extension) and left out the -shm and -wal files.

When I copied those two files together with the main database file to my PC, and opened the main .db file, the tables and its records were shown successfully in my database viewer.

Note: SQLite database files are available in /data/data/<the-app-package-name>/databases on the device. Accessing them may require root privileges.

See this post and its answers if you want to merge the files to the main database file.

For example, I created a separate DAO (Kotlin language) just for this:

import androidx.room.Dao
import androidx.room.RawQuery
import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery

@Dao
abstract class DatabaseDao {

    open suspend fun flushDatabase() {
        checkpoint(SimpleSQLiteQuery("pragma wal_checkpoint(full)"))
    }

    @RawQuery
    protected abstract suspend fun checkpoint(supportSQLiteQuery: SupportSQLiteQuery): Int
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sam
Solution 2 Aman Srivastava
Solution 3