I'm making an Android app with Jetpack Compose, Room and Dagger-Hilt.
The app crashes with following exception:
java.lang.RuntimeException: Cannot find implementation for com.pbpu.android.data.local.source.Database. Database_Impl does not exist
Project level build.gradle.kts
:
plugins {
id("com.android.application") version "8.1.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
id("com.google.devtools.ksp") version "1.8.10-1.0.9" apply false
id("com.google.dagger.hilt.android") version "2.47" apply false
}
The dependencies used are:
// DI
implementation("com.google.dagger:hilt-android:2.47")
ksp("com.google.dagger:hilt-compiler:2.47")
implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
// Room
implementation("androidx.room:room-ktx:2.5.2")
implementation("androidx.room:room-runtime:2.5.2")
ksp("androidx.room:room-compiler:2.5.2")
// Other dependencies
If I change dependencies to:
// DI
implementation("com.google.dagger:hilt-android:2.47")
ksp("com.google.dagger:hilt-compiler:2.47")
implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
// Room
implementation("androidx.room:room-ktx:2.5.2")
implementation("androidx.room:room-runtime:2.5.2")
kapt("androidx.room:room-compiler:2.5.2")
// Other dependencies
Then compilation fails with message:
path\to\file\RecordWithMarkingsDao.java:17: error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
com.pbpu.android.domain.model.RecordWithMarkings entity, @org.jetbrains.annotations.NotNull
^
But, same code compiles if I use ksp("androidx.room:room-compiler:2.5.2")
or even annotationProcessor("androidx.room:room-compiler:2.5.2")
but then, the app crashes with exception as stated before!
Record.kt
@Entity(tableName = "records")
data class Record(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(index = true)
var idRecord: Long = 0,
// Other fields
)
Marking.kt
@Entity(
tableName = "markings",
foreignKeys = [
ForeignKey(
entity = Record::class,
parentColumns = ["idRecord"],
childColumns = ["fkIdRecord"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE,
),
],
)
data class Marking(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(index = true)
var idMarking: Long = 0,
@ColumnInfo(index = true)
val fkIdRecord: Long = 0,
// Other fields
)
RecordWithMarkings.kt
data class RecordWithMarkings(
@Embedded
val record: Record,
@Relation(
parentColumn = "idRecord",
entityColumn = "fkIdRecord",
)
val markings: List<Marking>,
)
How to solve this problem?
Any help will be appreciated and ask for any additional information if required.
Thanks.
Looks like the issue is in the DAO, please ensure correctness:
RecordWithMarkingsDao.java
should have methods that deal with fetching RecordWithMarkings
objects. These methods should return RecordWithMarkings
or a list of RecordWithMarkings
but shouldn't take RecordWithMarkings
as an argument. Here is an example of what the DAO might look like:@Dao
interface RecordWithMarkingsDao {
@Transaction
@Query("SELECT * FROM records")
fun getAllRecordsWithMarkings(): List<RecordWithMarkings>
@Transaction
@Query("SELECT * FROM records WHERE idRecord = :recordId")
fun getRecordWithMarkings(recordId: Long): RecordWithMarkings
}
Record
and Marking
entities, for example:@Dao
interface RecordDao {
@Insert
fun insertRecord(record: Record): Long
@Update
fun updateRecord(record: Record)
@Delete
fun deleteRecord(record: Record)
}
@Dao
interface MarkingDao {
@Insert
fun insertMarking(marking: Marking): Long
@Update
fun updateMarking(marking: Marking)
@Delete
fun deleteMarking(marking: Marking)
}
This should help :)