Reputation: 39
I am trying to implement Database in a fresh app, but for some reason it's crashing and after a lot of searches I am posting this issue, I did not find anything relevant:
FATAL EXCEPTION: main (Ask Gemini)
Process: com.basic.app, PID: 19092
java.lang.RuntimeException: Cannot find implementation for com.basic.app.data.MyDatabase. MyDatabase_Impl does not exist
at androidx.room.Room.getGeneratedImplementation(Room.kt:58)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.kt:1351)
at com.basic.app.data.DatabaseProvider.getDatabase(DatabaseProvider.kt:18)
at com.basic.app.MainActivity$onCreate$1$1$1.invoke(MainActivity.kt:44)
at com.basic.app.MainActivity$onCreate$1$1$1.invoke(MainActivity.kt:36)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:117)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$1$bodyContentPlaceables$1.invoke(Scaffold.kt:239)
at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$1$bodyContentPlaceables$1.invoke(Scaffold.kt:221)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:1067)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:701)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:78)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3340)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3273)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:588)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1013)
at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:4007)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:721)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:694)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:685)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:669)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(SubcomposeLayout.kt:1014)
at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$1.invoke(Scaffold.kt:221)
at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$1.invoke(Scaffold.kt:128)
at androidx.compose.ui.layout.MeasureScope$layout$1.placeChildren(MeasureScope.kt:70)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure$1.placeChildren(SubcomposeLayout.kt:879)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1.invoke(LayoutNodeLayoutDelegate.kt:365)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1.invoke(LayoutNodeLayoutDelegate.kt:357)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2299)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:467)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeLayoutSnapshotReads$ui_release(OwnerSnapshotObserver.kt:83)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.layoutChildren(LayoutNodeLayoutDelegate.kt:357)
Here is my main activity code:
class MainActivity : ComponentActivity() {
private lateinit var database: MyDatabase
private lateinit var activityRepository: ActivityRepository
@SuppressLint("CoroutineCreationDuringComposition")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
WalkathonTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
if (!::database.isInitialized) {
database = DatabaseProvider.getDatabase(this)
}
// Initialize activityRepository if not already initialized
if (!::activityRepository.isInitialized) {
database.let { db ->
activityRepository = ActivityRepository(db.activityDao())
}
}
// Fetch all activities asynchronously
GlobalScope.launch(Dispatchers.IO) {
val activities = activityRepository.all()
// Loop through the activities
for (activity in activities) {
// Perform operations with each activity
Log.d("MainActivity", "Activity: $activity")
}
}
}
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
WalkathonTheme {
Greeting("Android")
}
}
Here is my Dao:
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
@Dao
interface ActivityDao {
@Insert
suspend fun insert(activity: ActivityModel)
@Update
suspend fun update(activity: ActivityModel)
@Delete
suspend fun delete(activity: ActivityModel)
@Query("SELECT * FROM activity")
suspend fun all(): List<ActivityModel>
}
Here is my model:
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.util.Date
@Entity(tableName = "activity")
data class ActivityModel(
@PrimaryKey(autoGenerate = true)
val id: Long = 0,
val steps: Int,
val createdAt: Date,
val updatedAt: Date? = null
)
Here is my repository:
class ActivityRepository(private val activityDao: ActivityDao) {
suspend fun all(): List<ActivityModel> {
return activityDao.all()
}
}
Here is my Database:
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [ActivityModel::class], version = 1)
abstract class MyDatabase : RoomDatabase() {
abstract fun activityDao(): ActivityDao
}
Here is my DatabaseProvider:
import android.content.Context
import androidx.room.Room
object DatabaseProvider {
private var INSTANCE: MyDatabase? = null
fun getDatabase(context: Context): MyDatabase {
synchronized(this) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
MyDatabase::class.java,
context.getString(R.string.database_name)
).build()
}
return INSTANCE!!
}
}
}
Here is my gradle:
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
}
android {
namespace = "com.basic.app"
compileSdk = 34
defaultConfig {
applicationId = "com.basic.app"
minSdk = 29
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = 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 {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation(libs.androidx.room.common)
implementation(libs.androidx.room.ktx)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
Version catalog:
[versions]
agp = "8.4.1"
kotlin = "1.9.0"
coreKtx = "1.10.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.6.1"
activityCompose = "1.8.0"
composeBom = "2023.08.00"
roomCommon = "2.6.1"
roomCompiler = "2.6.1"
roomKtx = "2.6.1"
roomRuntime = "2.6.1"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomCompiler" }
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomRuntime" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-room-common = { group = "androidx.room", name = "room-common", version.ref = "roomCommon" }
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
I wanted to run the app successfully, but it's crashing.
Upvotes: 1
Views: 170
Reputation: 3025
Actually @Majedul Islam was correct, just failed to show how to add the dependency correctly:
in build.gradle to plugin block add:kotlin("kapt")
like so:
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
kotlin("kapt")
}
then in dependencies
add kapt(libs.androidx.room.compiler)
as you were missing only this one
in the end make sure all 3 of those dependencies are there (don't add all 3 as you had some of them)
implementation(libs.androidx.room.common)
implementation(libs.androidx.room.ktx)
kapt(libs.androidx.room.compiler)
and it fixes your problem, however it will still not build since you're using a Date in your entity (and that requires a type converter)
so create a class Converter
class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}
@TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time?.toLong()
}
}
and in your database add: @TypeConverters(Converters::class)
so it looks like this:
@Database(entities = [ActivityModel::class], version = 1)
@TypeConverters(Converters::class)
abstract class Database : RoomDatabase() {
abstract fun activityDao(): ActivityDao
}
Upvotes: 0