Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DAO Injection problem - RoomDatabase not found with Hilt Android

So I'm trying to use Room on a personnal project. I have implemented my entities, dao and my roomdatabase extended application class :

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

    companion object {
        const val DATABASE_NAME = "MyDb"
    }

    abstract fun getUserDao(): UserDao
}

However, I'm also trying to use Hilt DI with it, so, I created a module like that :

@InstallIn(ApplicationComponent::class)
@Module
object PersistenceModule {

    lateinit var database: MyDatabase

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext context: Context): MyDatabase{
        database =  Room.databaseBuilder(
            context,
            MyDatabase::class.java,
            MyDatabase.DATABASE_NAME
        )
            .fallbackToDestructiveMigration()
            .build()

        return database
    }

    @Provides
    @Singleton
    fun provideUserDao(db: MyDatabase): UserDao {
        return db.getUserDao()
    }
}

Everything seems good to me. However, when I try to compile, I've got this error message :

class file for androidx.room.RoomDatabase not found

Any idea of what I missed ?

If it can help you, I tried to change my build.gradle from this :

implementation "androidx.room:room-runtime:2.3.0-alpha02"

To this :

api "androidx.room:room-runtime:2.3.0-alpha02"

And with that, it compiles succefully, but I don't think it's a good practice, looking the tutorials I found.

Don't hesitate if you need more details on my code.

Thank you for your answers :)

EDIT :

My build.gradle for Room :

implementation "androidx.room:room-runtime:2.3.0-alpha02"
kapt "androidx.room:room-compiler:2.3.0-alpha02"
implementation "android.arch.persistence.room:runtime:1.1.1"
kapt "android.arch.persistence.room:compiler:1.1.1"

With this also :

apply plugin: 'kotlin-kapt'

EDIT 2 :

I think I found what is the cause of the problem. I called my DAO method in a class like that :

@Singleton
class DBManagerImpl @Inject constructor(
    private val userDao: UserDao
) : DBManager {

    override fun insertUser(userDBEntity: UserDBEntity) {
       userDao.insertUser(userDBEntity)
    }
}

It seems the problem is in the userDao injection cause if I comment the "private val userDao: UserDao" line, I don't have the error anymore. So I think my problem comes from my way to inject the dao object.

like image 686
Boysteuf Avatar asked Mar 02 '23 03:03

Boysteuf


2 Answers

I faced that problem because I was adding dependencies of room to the core module so for those who using modular architecture be sure you added dependencies of room to the app module also

like image 80
Mostafa Anter Avatar answered Apr 07 '23 06:04

Mostafa Anter


Since you did not provide how you created your dao object, I've written my own and provide it in this answer. This should work:

Database Class

@Database(version = 1,entities = [UserDBEntity::class])
abstract class MyDataBase() : RoomDatabase() {
    
   abstract fun myDao(): UserDao

   companion object {
      val DATABASE_NAME = "my_db"
   }
}

DAO

@Dao
inteface UserDao {
   // your functions
   @Query("SELECT * FROM UserDBEntity")
   suspend fun get(): List<User>

   @Insert(onConflict = OnConflictStrategy.REPLACE)
   suspend fun insert(entity: UserDBEntity)
}

Room Module

@InstallIn(ApplicationComponent::class)
@Module
object RoomModule {
   @Singleton
   @Provides
   fun provideMyDB(@ApplicationContext context: Context): MyDataBase {
       return Room.databaseBuilder(context, 
               MyDataBase::class.java,
               MyDataBase.DATABASE_NAME
         ).fallbackToDestructiveMigration().build()
   }
}

@Singleton
@Provides
fun provideMyDao(myDB: MyDataBase): UserDao {
    return myDB.myDao()
}
like image 38
Andrew Avatar answered Apr 07 '23 07:04

Andrew