Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RoomDatabaseConstructor on KotlinMultiplatform has no corresponding expected declaration

I have implemented the latest version of Room in my KMP project (roomCommon = "2.7.0-alpha06" ). The new version change the instantiation setup for a RoomDatabase in a KMP project

https://developer.android.com/jetpack/androidx/releases/room#2.7.0-alpha06

Now we have to implement RoomDatabaseConstructor.

So that's my database file on commonMain directory:

import androidx.room.ConstructedBy
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.RoomDatabaseConstructor
import data.database.dao.UserPreferencesDAO
import data.database.entities.UserPreferencesEntity

const val DATABASE_NAME = "app_database.db"

expect object MyDatabaseCtor : RoomDatabaseConstructor<AppDatabase>

@Database(entities = [UserPreferencesEntity::class], version = 1)
@ConstructedBy(MyDatabaseCtor::class)
abstract class AppDatabase : RoomDatabase(), DB {
    abstract fun getDao(): UserPreferencesDAO
    override fun clearAllTables(): Unit {}
}

interface DB {
    fun clearAllTables(): Unit {}
}

Them, after that I have implemented my actual functions on androidMain and iosMain

iOS:

actual object MyDatabaseCtor : RoomDatabaseConstructor<AppDatabase> {
    override fun initialize(): AppDatabase {
        return getDatabase()
    }
}

fun getDatabase(): AppDatabase {
    return Room.databaseBuilder<AppDatabase>(name = DATABASE_NAME).setDriver(BundledSQLiteDriver())
        .setQueryCoroutineContext(Dispatchers.IO).build()
}

Android:

actual object MyDatabaseCtor : RoomDatabaseConstructor<AppDatabase>{

    private val appContext = RickMortyApp.context
    override fun initialize(): AppDatabase {
        val dbFile = appContext.getDatabasePath(DATABASE_NAME)
        return Room.databaseBuilder<AppDatabase>(appContext, dbFile.absolutePath)
            .setDriver(BundledSQLiteDriver())
            .setQueryCoroutineContext(Dispatchers.IO)
            .build()
    }
}

The problem is when I build the code I get a autogenerated class

public actual object MyDatabaseCtor : RoomDatabaseConstructor<AppDatabase> {
  override fun initialize(): AppDatabase = `data`.database.AppDatabase_Impl()
}

And my Actual/Expected classes start to fail with the next message:

**Error1:**

project/composeApp/build/generated/ksp/metadata/commonMain/kotlin/data/database/MyDatabaseCtor.kt:5:22 'actual object MyDatabaseCtor : RoomDatabaseConstructor<AppDatabase>' has no corresponding expected declaration

**Error 2:**

Redeclaration:
actual object MyDatabaseCtor : RoomDatabaseConstructor<AppDatabase>

**Error 3:**

/composeApp/src/androidMain/kotlin/data/database/Database.android.kt:13:15 'actual object MyDatabaseCtor : RoomDatabaseConstructor<AppDatabase>' has no corresponding expected declaration

I tried to clean project to remove de autogenerated class but after compile is the same error class.

like image 371
Aris Guimerá Avatar asked Feb 12 '26 13:02

Aris Guimerá


2 Answers

Ok I think I figured this out.

I replaced this line

dependencies.kspCommonMainMetadata(libs.room.compiler)

with this:

dependencies {
    listOf(
        "kspAndroid",
        // "kspJvm",
        "kspIosSimulatorArm64",
        "kspIosX64",
        "kspIosArm64"
    ).forEach {
        add(it, libs.room.compiler)
    }
}

Based on the advice here: https://issuetracker.google.com/issues/342905180#comment21

I also removed this code which was a workaround for errors in the previous version

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>().configureEach {
    if (name != "kspCommonMainKotlinMetadata") {
        dependsOn("kspCommonMainKotlinMetadata")
    }
}

For some reason JVM is still not working with this error, which is why I have it commented out for the moment: Configuration with name 'kspJvm' not found.

like image 175
avatar_aang Avatar answered Feb 15 '26 11:02

avatar_aang


Changed build.gradle.kts (app level) file like this

ksp { arg("room.schemaLocation","${projectDir}/schemas") } added dependencies:

dependencies { 

    // Android

    add("kspAndroid", libs.room.compiler)

    // JVM (Desktop)

    add("kspDesktop", libs.room.compiler)

    // iOS

    add("kspIosSimulatorArm64", libs.room.compiler)

    add("kspIosX64", libs.room.compiler)

    add("kspIosArm64", libs.room.compiler)

}

It worked for me.

like image 45
Laraib Ishtiaq Avatar answered Feb 15 '26 11:02

Laraib Ishtiaq