Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cannot find implementation ( Room )

I have an issue with Room or idk actually where the problem is and I need help to find out where is the problem, I'm using Hilt DI, the moment that creating an instance of database it crashes here's my code

Error

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.todo, PID: 1895
    java.lang.RuntimeException: cannot find implementation for com.example.todo.data.ToDoDatabase. ToDoDatabase_Impl does not exist
        at androidx.room.Room.getGeneratedImplementation(Room.java:97)
        at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:1358)
        at com.example.todo.di.AppModule.provideToDoDatabase(AppModule.kt:27)
        at com.example.todo.di.AppModule_ProvideToDoDatabaseFactory.provideToDoDatabase(AppModule_ProvideToDoDatabaseFactory.java:33)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.toDoDatabase(DaggerMainApplication_HiltComponents_SingletonC.java:69)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.access$2000(DaggerMainApplication_HiltComponents_SingletonC.java:48)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:583)
        at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.toDoDao(DaggerMainApplication_HiltComponents_SingletonC.java:73)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC.access$1900(DaggerMainApplication_HiltComponents_SingletonC.java:48)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:580)
        at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.toDoRepository(DaggerMainApplication_HiltComponents_SingletonC.java:448)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.toDoViewModel(DaggerMainApplication_HiltComponents_SingletonC.java:452)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl.access$1700(DaggerMainApplication_HiltComponents_SingletonC.java:429)
        at com.example.todo.DaggerMainApplication_HiltComponents_SingletonC$ViewModelCImpl$SwitchingProvider.get(DaggerMainApplication_HiltComponents_SingletonC.java:487)
        at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$1.create(HiltViewModelFactory.java:100)
        at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69)
        at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:84)
        at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:109)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:171)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:44)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:31)
        at com.example.todo.fragments.add.AddFragment.getViewModel(AddFragment.kt:20)
        at com.example.todo.fragments.add.AddFragment.insertDataToDo(AddFragment.kt:63)
        at com.example.todo.fragments.add.AddFragment.onOptionsItemSelected(AddFragment.kt:45)
        at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3122)
        at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:3226)
        at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3126)
        at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:3226)
        at androidx.fragment.app.FragmentController.dispatchOptionsItemSelected(FragmentController.java:416)
        at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:358)
        at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:264)
        at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
        at androidx.appcompat.app.AppCompatDelegateImpl.onMenuItemSelected(AppCompatDelegateImpl.java:1179)
        at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
        at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:975)
        at androidx.appcompat.widget.ActionMenuView.invokeItem(ActionMenuView.java:624)
        at androidx.appcompat.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:151)
        at android.view.View.performClick(View.java:7441)
        at android.view.View.performClickInternal(View.java:7418)
        at android.view.View.access$3700(View.java:835)
        at android.view.View$PerformClick.run(View.java:28676)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7842)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

build.gradle

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'androidx.navigation.safeargs.kotlin'
    id 'dagger.hilt.android.plugin'
    id 'kotlin-parcelize'
}

android {
    compileSdk 31

    defaultConfig {
        applicationId "com.example.todo"
        minSdk 24
        targetSdk 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }

    buildFeatures {
        dataBinding true
        viewBinding true
    }
}

dependencies {
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    def nav_version = "2.3.5"
    def room_version = "2.3.0"
    def lifecycle_version = "2.4.0"

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
    testImplementation 'junit:junit:'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    //Navigation component
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

    //Room
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"

    // Lifecycle
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"

    //Kotlin coroutines
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'

    //RecyclerView
    implementation 'jp.wasabeef:recyclerview-animators:4.0.2'

    //Hilt DI
    implementation "com.google.dagger:hilt-android:2.38.1"
    kapt "com.google.dagger:hilt-compiler:2.38.1"

}

ToDoData.kt

@Entity(tableName = "todo_table")
@Parcelize
data class ToDoData(
    @PrimaryKey(autoGenerate = true)
    var id: Int,
    var title: String,
    var description: String,
    var priority: Priority
) : Parcelable

ToDoDatabase.kt

@Database(entities = [ToDoData::class], version = 1, exportSchema = false)
@TypeConverters(Converter::class)
abstract class ToDoDatabase : RoomDatabase() {

    abstract fun toDoDao(): ToDoDao

}

ToDoViewModel.kt

@HiltViewModel
class ToDoViewModel @Inject constructor(
    private val repository: ToDoRepository
) : ViewModel() {

    private val getAllData: LiveData<List<ToDoData>> = repository.getAllData

    fun insertData(toDoData: ToDoData) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.insertData(toDoData)
        }
    }
}

AppModule.kt

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Singleton
    @Provides
    fun provideToDoDatabase(
        @ApplicationContext app: Context
    ) = Room.databaseBuilder(
        app,
        ToDoDatabase::class.java,
        "todo_database"
    )
        .fallbackToDestructiveMigration()
        .build()

    @Singleton
    @Provides
    fun provideTodoDao(db: ToDoDatabase) = db.toDoDao()

}

AddFragment.kt

And here's the function that I call to insert data from AddFragment

    private val viewModel: ToDoViewModel by viewModels()


private fun insertDataToDo() {
        val title = binding.titleEt.text.toString()
        val priority = binding.spinnerPriorities.selectedItem.toString()
        val description = binding.descriptionEt.text.toString()

        val validation = verifyDataFromUser(title, description)
        if (validation) {
            val data = ToDoData(
                0,
                title,
                description,
                parsePriority(priority)
            )
            viewModel.insertData(data)
            Toast.makeText(requireContext(), "Successfully Added!", Toast.LENGTH_SHORT).show()

            findNavController().navigate(R.id.action_addFragment_to_listFragment)
        } else
            Toast.makeText(requireContext(), "Please fill out all fields", Toast.LENGTH_SHORT)
                .show()


    }

    private fun verifyDataFromUser(title: String, description: String): Boolean {
        return if (TextUtils.isEmpty(title) || TextUtils.isEmpty(description)) {
            false
        } else !(title.isEmpty() || description.isEmpty())
    }

    private fun parsePriority(priority: String): Priority {
        return when (priority) {
            "High Priority" -> Priority.HIGH
            "Medium Priority" -> Priority.MEDIUM
            "Low Priority" -> Priority.LOW
            else -> Priority.LOW
        }
    }

I have already seen some questions here with the same problem but it didn't work for me so idk exactly where the problem here

like image 392
Eslam Ali Avatar asked Oct 20 '25 04:10

Eslam Ali


1 Answers

I had exactly the same problem as you, and after half a day of trying to rewrite and delete the pieces of code, finally my problem was solved by changing annotationProcessor to kapt in the build.gradle file.

// Hilt, Dependency injection
def hilt_version = "2.38.1"
implementation "com.google.dagger:hilt-android:$hilt_version"
annotationProcessor "com.google.dagger:hilt-compiler:$hilt_version"

// Room database
def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"

After change and fixed:

// Hilt, Dependency injection
def hilt_version = "2.38.1"
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"

// Room database
def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

Given the error text that was printed on the console, I did not think it was a problem at all!

like image 169
Majid Ahmadi Jebeli Avatar answered Oct 22 '25 17:10

Majid Ahmadi Jebeli