How to check if data is inserted in Room Database

Viewed 34921

I am using Room Database from the new Architecture components in my project. I am adding some data through dao, but when trying to retrieve it I am not getting it. Can you please suggest me how to check whether the insert was successful or not? Below are the codes to help you understand the problem.

adding to database, I checked with debugger, this statement executed successfully.

appContext.db.rallyDAO().addVehicleListItem(vehicle)

Getting null from database on this statement after insert.

val v = appContext.db.rallyDAO().getVehicleListItem(it.vehicleID)

RoomDatabase

@Database(entities = arrayOf(Rally::class, Route::class, CheckPoints::class, Vehicles::class, VehicleListItem::class), version = 1)
abstract class TSDRoom: RoomDatabase() {
    public abstract fun rallyDAO():RallyDAO
}

Inside DAO

@Insert(onConflict = OnConflictStrategy.REPLACE)
    fun addVehicleListItem(vehicleListItem:VehicleListItem)

    @Query("select * from vehicles_submitted where vehicle_id LIKE :vehicleID")
    fun getVehicleListItem(vehicleID:String):VehicleListItem

VehicleListItem Entity

@Entity(tableName = "vehicles_submitted",
        foreignKeys = arrayOf(ForeignKey(entity = Rally::class,
                parentColumns = arrayOf("rally_id"),
                childColumns = arrayOf("rally_id"))))
class VehicleListItem {
    @PrimaryKey
    @ColumnInfo(name = "vehicle_id")
    @SerializedName("vehicle_id")
    var vehicleID : String = ""
    @ColumnInfo(name = "driver_id")
    @SerializedName("driver_id")
    var driverID : String = ""
    @ColumnInfo(name = "vehicle_name")
    @SerializedName("vehicle_name")
    var vehicleName : String = ""
    @ColumnInfo(name = "driver_name")
    @SerializedName("driver_name")
    var driverName : String = ""
    @ColumnInfo(name = "driver_email")
    @SerializedName("driver_email")
    var driverEmail : String = ""

    @ColumnInfo(name = "rally_id")
    @SerializedName("rally_id")
    var rallyID: String = ""

    @ColumnInfo(name = "is_passed")
    @SerializedName("is_passed")
    var isPassed = false

    @ColumnInfo(name = "passing_time")
    @SerializedName("passing_time")
    var passingTime:String=""
}
8 Answers

There are two cases regarding insertion.

Dao methods annotated with @Insert returns:

  1. In case the input is only one number it returns a Long, check whether this Long equals One, if true then the Item was added successfully.

     @Insert
     suspend fun insert( student: Student): Long
    
  2. In case the input is varargs it returns a LongArray, check whether the size of varargs equals the LongArray size, if true then items were added successfully

     @Insert
     suspend fun insert(vararg students: Student): LongArray
    

There are multiple ways you can test that.

  1. As @Ege Kuzubasioglu mentioned you can use stetho to check manually (Need minor change to code).
  2. Pull database file from "data/data/yourpackage/databases/yourdatabase.db" to your local machine and use any applications to read the content inside the database. I personally use https://sqlitebrowser.org/. Pulling database file can be done either using the shell commands or use "Device File Explorer" from android studio.

  3. Write TestCase to see if it is working. Here is an example of test case from one of my projects.

    // Code from my DAO class

    @Insert(onConflict = OnConflictStrategy.REPLACE) public abstract Long[] insertPurchaseHistory(List MusicOrders);

//My Test Case @Test public void insertPurchaseHistoryTest() {

    // Read test data from "api-responses/music-purchase-history-response.json"
    InputStream inputStream = getClass().getClassLoader()
            .getResourceAsStream("api-responses/music-purchase-history-response.json");
    // Write utility method to convert your stream to a string.
    String testData = FileManager.readFileFromStream(inputStream);

    // Convert test data to "musicOrdersResponse"
    MusicOrdersResponse musicOrdersResponse = new Gson().fromJson(testData,MusicOrdersResponse.class);

    // Insert inmateMusicOrders and get the list of
    Long[] rowsInserted = tracksDao.insertPurchaseHistory(musicOrdersResponse.getmusicOrders());
    assertThat(rowsInserted.length,Matchers.greaterThan(0));
}

One of the easiest way is:

  1. First download DB Navigator as plugin in Android Studio(For more visit: https://plugins.jetbrains.com/plugin/1800-database-navigator).

  2. Go to view> Tools Window> Device File explorer and download the instance of your DB.

  3. Open DB Browser(From left Pane window) and browse your DB instance you have downloaded. Setup the connection and you are good to browser you database.

  4. For more info please refer to the link provided above.

I make like this(I use coroutines suspend):

class SaveVehicle(val repository: RepositoryInterface) {
    suspend fun invoke(vehicleListItem: VehicleListItem): VehicleListItem = 
        with(vehicleListItem) {
           also {
                 repository.saveVehicle(vehicleListItem)
           }
        }
}

Kotlin Doc

inline fun <T> T.also(block: (T) -> Unit): T

Calls the specified function block with this value as its argument and returns this value.

also is good for performing some actions that take the context object as an argument. Use also for actions that need a reference rather to the object than to its properties and functions, or when you don't want to shadow this reference from an outer scope.

You can check my example in GitHub:

Related