I was developing sme regular room app where I try to keep same data into a localdatabase using room. I'm getting the following error:
error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
java.lang.String tocd);
^
Regarding my LocaDatabase class is this:
@Database(entities = [SessionData::class], version = 1, exportSchema = true)
abstract class LocalDatabase : RoomDatabase() {
abstract fun dao(): CepsaDAO
}
My data class model:
@Entity(tableName = Constants.DB_NAME)
data class SessionData (
@PrimaryKey(autoGenerate = false) val tcod: String,
@ColumnInfo(name = "sessionToken") val sessionToken: String,
)
And my DAO:
@Dao
interface CepsaDAO {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertTocd(tocd: String):Long //This method rise the error
@Query("SELECT tcod FROM ${Constants.DB_NAME}")
fun getTocd():String?
@Query("SELECT sessionToken FROM ${Constants.DB_NAME} WHERE tcod=:tocd")
fun getSessionData(tocd:String): String?
@Query("DELETE FROM ${Constants.DB_NAME} WHERE sessionToken=:token")
fun deleteSessionId(token: String):Int
}
And in order to instanciate i'm using dagger plugin:
@InstallIn(SingletonComponent::class)
@Module
class LocalModule {
@Provides
@Singleton
fun provideDB(@ApplicationContext context: Context): LocalDatabase {
return Room.databaseBuilder(
context.applicationContext,
LocalDatabase::class.java,
Constants.DB_NAME
).build()
}
}
@ActivityRetainedScoped
class LocalDatabaseUseCase @Inject constructor(@ApplicationContext val context: Context) {
@Inject
lateinit var db : LocalDatabase
... Some code
}
So I see some solution in stackoverflow and github forums, like downground the kotlin version or the upgrade the room version, but doesn't work.
Here is my build.gralde(app):
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
id 'org.jetbrains.kotlin.plugin.serialization'
}
dependencies{
kotlin_version=1.8.10
kotlin_serialization=1.5.0
core_ktx_version=1.10.1
room_version=2.5.0
implementation "androidx.core:core-ktx:$core_ktx_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
implementation 'androidx.activity:activity-compose:1.7.2'
implementation platform('androidx.compose:compose-bom:2022.10.00')
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-graphics'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.compose.material3:material3'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialization"
//Room libraries
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// To use Kotlin annotation processing tool (kapt)
implementation "androidx.room:room-ktx:$room_version"
}
So, what am I missing?
Thanks in advance !
You have:-
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertTocd(tocd: String):Long //This method rise the error
The insertTocd
function is trying/saying to insert into the table that is defined via the String class. The kotlin String class does not have the @Entity
annotation. Obviously it never would or could. It is part of Kotlin.
When you insert into the database you insert data into the column(s) of a table table. Room determines the table(s) via the classes specified in the entities
parameter of the @Database
annotation. The columns for a table are ascertained according to the fields of the @Entity
annotated class(es).
You have a single class so defined according to @Database(entities = [SessionData::class], version = 1, exportSchema = true)
as such you can only insert data into the Constants.DB_NAME
table. When using the convenience @Insert
then the object type passed to the function must be an @Entity
annotated class that is defined via the entities parameter of the @Database
annotation.
It would appear that you are trying to insert a row into the table just using the tcod value.
What you could do is use an @Query
to do the insert e.g.
@Query("INSERT OR REPLACE INTO ${Constants.DB_NAME} VALUES(:tcod,'whatever would be a suitable default value');")
fun insertTocd(tcod: String)
Alternately and perhaps more likely what you want, you could use something like:-
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(sessionData: SessionData): Long
fun insertTocd(tcod: String): Long {
return insert(SessionData(tcod,"whatever would be a suitable default value")
}
note this would return a value, it would be the rowid of the inserted row. rowid is a special column, that always exists for tables (when using Room). If the row could not be inserted then the value would be -1.
both cases whatever would be a suitable default value
could be any value but not null as the type String will have a NOT NULL constraint applied.