-1

I am trying to make a copy of the following Java class in Kotlin.

@Database(entities = {Word.class}, version = 1)
public abstract class WordRoomDatabase extends RoomDatabase {

   public abstract WordDao wordDao();

   private static WordRoomDatabase INSTANCE;


   static WordRoomDatabase getDatabase(final Context context) {
       if (INSTANCE == null) {
           synchronized (WordRoomDatabase.class) {
               if (INSTANCE == null) {
                   INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                           WordRoomDatabase.class, "word_database")
                           .build();                
               }
           }
       }
       return INSTANCE;
   }
}

I am following a tutorial by code labs to implement a simple SQLite data base using Room. Following is my complete Kotlin implementation of the class.

@Database(entities = [Word::class], version = 1)
abstract class WordRoomDatabase : RoomDatabase() {

    abstract fun wordDao(): WordDao

    private class PopulateDbAsync(db: WordRoomDatabase) : AsyncTask<Unit, Unit, Unit>() {

        private val dao = db.wordDao()

        override fun doInBackground(vararg params: Unit) {
            dao.deleteAll()
            var word = Word("Hello")
            dao.insert(word)
            word = Word("World")
            dao.insert(word)
        }
    }

    companion object {
        private var INSTANCE: WordRoomDatabase? = null

        private val roomDatabaseCallback = object : RoomDatabase.Callback() {

            override fun onOpen(db: SupportSQLiteDatabase) {
                super.onOpen(db)
                PopulateDbAsync(INSTANCE as WordRoomDatabase).execute()
            }
        }

        fun getDatabase(context: Context): WordRoomDatabase {
            if (INSTANCE == null) {
                synchronized(WordRoomDatabase::class) {
                    if (INSTANCE == null) {
                        INSTANCE = Room.databaseBuilder(context.applicationContext,
                                WordRoomDatabase::class.java, "word_database")
                                .addCallback(roomDatabaseCallback)
                                .build()
                    }
                }
            }

            return INSTANCE as WordRoomDatabase
        }
    }
}

When I try to access the data inside the companion object I get the following error. cannot find implementation for com.fifthgen.androidroomtest.data.WordRoomDatabase.WordRoomDatabase_Impl does not exist

This is the line of code where the error occurs.

private val db = WordRoomDatabase.getDatabase(application)
Saminda Peramuna
  • 735
  • 9
  • 22
  • 1
    Don't use the the INSTANCE property, instead use the getDatabase(context) method directly. If you need the Context in the AsyncTask then store the Context received as a parameter in a property. – user May 18 '18 at 05:11
  • have you created WordDao interface with @Dao annotation – DB377 May 18 '18 at 05:13
  • @DharakBhatt Yes I have it implemented. – Saminda Peramuna May 18 '18 at 05:16
  • @Luksprog I think the issue is with initialising the `INSTANCE` object, when using `WordRoomDatabase::class.java` because I get the same error when just using the method. The JavaDoc says the parameter needed is a `kclass : Class`. – Saminda Peramuna May 18 '18 at 05:21
  • You're coding up the notoriously broken variant of the [double-checked locking](https://stackoverflow.com/questions/3578604/how-to-solve-the-double-checked-locking-is-broken-declaration-in-java) idiom. – Marko Topolnik May 18 '18 at 06:01
  • 1
    @SamindaPeramuna The problem is that the code doesn't generate your database implementation. I've also seen this right now and I solved by deleting the .gradle folder and rebuilding the project. Also, make sure you're using kapt for the room compiler. – user May 18 '18 at 06:04
  • @Luksprog Thanks for the answer. using `kapt` did the trick. – Saminda Peramuna May 18 '18 at 06:18

1 Answers1

0

Added room compiler and Kotlin plugin to the build.gradle as Luksprog suggested and everything is working fine.

apply plugin: 'kotlin-kapt'

// .....

kapt 'android.arch.persistence.room:compiler:1.1.0'
Saminda Peramuna
  • 735
  • 9
  • 22