简体   繁体   中英

java.lang.RuntimeException: cannot find implementation for com.example.laptopsdb.AppDatabase. AppDatabase_Impl does not exist (July 2022)

Yes I have already tried some old guides, I described it below.

I created new project for Room Database in Kotlin Android. I followed the official google documentation for it.

https://developer.android.com/training/data-storage/room

If I follow as per documentation I get error

java.lang.RuntimeException: cannot find implementation for com.example.laptopsdb.AppDatabase. AppDatabase_Impl does not exist

I also tried changing room-runtime to room-ktx but the error is same. Moreover, I tried adding id 'kotlin-kapt' and changing annotationProcessor to kapt but that give me following error, errors actually, bunch of them, while auto opening UserDao.java file

https://github.com/subjectOneThree/StackOverFLowShares/blob/main/Screenshot_20220715_215040.png

My code is almost stock according to documentation, however you can checkout if I made any stupid mistake

build.gradle (app)

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'

    //id 'kotlin-kapt'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.laptopsdb"
        minSdk 21
        targetSdk 32
        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'
    }
}

dependencies {

    apply plugin: "kotlin-kapt"

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    def room_version = "2.4.2"

    //implementation "androidx.room:room-ktx:$room_version"

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

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}

User.kt

@Entity (tableName = "laptops")
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

UserDao.kt

@Dao
interface UserDao {
    @Query("SELECT * FROM laptops")
    suspend fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    suspend fun loadAllByIds(userIds: IntArray): List<User>

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
            "last_name LIKE :last LIMIT 1")
    suspend fun findByName(first: String, last: String): User

    @Insert
    suspend fun insertAll(vararg users: User)

    @Delete
    suspend fun delete(user: User)
}

AppDatabase.kt

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "laptops"
        ).build()

        val userDao = db.userDao()

        GlobalScope.launch(Dispatchers.Default) {
            userDao.insertAll(User(2,"Hello","World"))

            val users: List<User> = userDao.getAll()
            Log.d("Room Activity", users.toString())
        }


    }
}

Some of the older project, and a project from my friend have exactly the same code (as far as I have looked into it) and they are working fine. But now when I am trying to create new project it is giving me error. I have tried building several projects before posting here.

  1. (comment) doing this:
val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "laptops"
        ).build()

in the onCreate of mainActivity is a very bad way of creating a database instance, unless you want multiple database instances in one app!

  1. solution:

try changing your build.gradle to this:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}
apply plugin: 'kotlin-kapt'

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.laptopsdb"
        minSdk 21
        targetSdk 32
        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'
    }
}

dependencies {
    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    def room_version = "2.4.2"

    kapt("androidx.room:room-compiler:2.4.2")
    implementation("androidx.room:room-runtime:2.4.2")
    implementation("androidx.room:room-ktx:2.4.2")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}

EDIT: After creating a project with the same code you have I noticed some rather strange bugs:

  1. in your User.kt file you declared the table name of that entity to "laptops", but in your UserDao you still refered to a table named user, which does not exist (???), that's why room had some troubles with your dao

  2. You declare your uid as Primary Key, which SHOULD NEVER be a duplicate, every single one of the keys should differ, yet in your main activity you use "userDao.insertAll(User(2,"Hello","World"))", which will result in a crash on second run, just remove that line

  3. using "GlobalScope.launch(Dispatchers.Default)" to run a coroutine isn't really encouraged, GlobalScope is even marked in the android studio as a delicate API and using it without proper knowledge first may result in strange bugs or even memory leaks, just use a viewModel to handle all of the work

  4. As I also stated before,

        val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "laptops"
        ).build()

do not use that to create database instance

  1. update your build.gradle to:
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}
apply plugin: 'kotlin-kapt'

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.laptopsdb"
        minSdk 21
        targetSdk 32
        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'
    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    // you may add the variable, just keep the version correct
    implementation "androidx.room:room-runtime:2.5.0-alpha02"
    implementation "androidx.room:room-ktx:2.5.0-alpha02"
    kapt "androidx.room:room-compiler:2.5.0-alpha02"

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}

and the dao to:

@Dao
interface UserDao {
    @Query("SELECT * FROM laptops")
    suspend fun getAll(): List<User>

    @Query("SELECT * FROM laptops WHERE uid IN (:userIds)")
    suspend fun loadAllByIds(userIds: IntArray): List<User>

    @Query("SELECT * FROM laptops WHERE first_name LIKE :first AND " +
            "last_name LIKE :last LIMIT 1")
    suspend fun findByName(first: String, last: String): User

    @Insert
    suspend fun insertAll(vararg users: User)

    @Delete
    suspend fun delete(user: User)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM