42

I am using Room architecture component for persistence. I have created generic DAO interface to avoid boilerplate code. Room Pro Tips

But my code doesn't compile saying "Error:(21, 19) error: Type of the parameter must be a class annotated with @Entity or a collection/array of it." for the Generic class T.

interface BaseDao<T> {

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(T... entity);

@Update
void update(T entity);

@Delete
void delete(T entity);
}

@Dao
public abstract class ReasonDao implements BaseDao<ReasonDao> {

   @Query("SELECT * from Reason")
   abstract public List<Reason> getReasons();

}

Is there anything I am missing here. It works like this here

3
  • 1
    where is your data class? Commented Dec 28, 2017 at 22:51
  • did you find the solution? Commented Mar 8, 2018 at 18:31
  • Yes, the accepted answer worked for me. Commented Mar 9, 2018 at 6:17

19 Answers 19

72

Changed in gradle from this:

kapt "androidx.room:room-compiler:$roomVersion"

to this:

annotationProcessor "androidx.room:room-compiler:$room_version"
Sign up to request clarification or add additional context in comments.

5 Comments

This one solved mine!
that is the solution for me, but why? I added kapt in plugins !
Changing this setting just led me to other errors. I just had to change the room version in the build.gradle (project) file as explained here: stackoverflow.com/a/73304737/1722652
instead of doing this add the "ktx" compiler implementation "androidx.room:room-ktx:$android_room" instead and leave kapt alone
This solve my problem and save my day. Thanks
13

I had initially followed the method used in Kotlin, but that gives the error in Java code. Two quick changes fixed it for me

  • Change BaseDao to Abstract class
  • Added @Dao annotation to the BaseDao

Please find the code below and now it runs properly

@Dao
abstract class BaseDao<T> {

   @Insert(onConflict = OnConflictStrategy.REPLACE)
   abstract void insert(T entity);

   @Update
   abstract void update(T entity);

   @Delete
   abstract void delete(T entity);
 }

 @Dao
 public abstract class ReasonDao extends BaseDao<Reason>{

    @Query("SELECT * from Reason")
    abstract public List<Reason> getReasons();

  }

1 Comment

Hello, according to my experience. When you get such error, try to comment all methods and sequentially uncomment each of them and rebuild every time.
11

If you faced this issue in Kotlin 1.7.10+ and Room < 2.4.2, upgrading Room to 2.4.3 fixes the issue.

From Room's changelog for 2.4.3: Fixed an issue that would cause Room to not recognize suspend functions in Kotlin 1.7

This issue was due to using suspend functions for insert/delete in interfaces: https://issuetracker.google.com/issues/236612358

1 Comment

Solved the error for me
8

remove suspend,then it will work.

@Dao
interface FoodDao {

     @Insert(onConflict = OnConflictStrategy.REPLACE)
     fun upsert(meal: Meal): Long


    @Query("SELECT * FROM food_tables")
    fun getAllFood(): LiveData<List<Meal>>


    @Delete
    fun deleteFood(meal: Meal)

}

Comments

6

The reason is that you specified ReasonDao type as generic parameter instead of Reason.

Original code:

@Dao
public abstract class ReasonDao implements BaseDao<ReasonDao> {

   ...

}

Correct code:

@Dao
public abstract class ReasonDao implements BaseDao<Reason> {

   ...

}

where Reason is the type marked with @Entity annotation.

By the way, this is fixed in the accepted answer, but is not mentioned in the changelist :)

Comments

6

The problem was that in my build.gradle, the version of Kotlin I was using was 1.5.0

implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.0"

But as far as I understood, this version of Kotlin along with Room and coroutines doesn’t work well. Was able to resolve the issue by downgrading the Kotlin version to:

implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.32"

Solved! Thank me later

1 Comment

That works for me also.
4

Changed in gradle this: kapt "androidx.room:room-compiler:$roomVersion" to this: annotationProcessor "androidx.room:room-compiler:$room_version"

Doing this solution served me partially but when trying to insert a date in the database it did not work for me so try kapt "androidx.room:room-compiler:$roomVersion" and rather change room_version to the latest stable version https://developer.android.com/jetpack/androidx/releases/room#groovy ependencies {

//**
def room_version = '2.4.0'
def activityVersion = '1.4.0'
def lifecycle_version = "2.2.0"
// Room and Lifecycle dependencies
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
//kotlin extensions for coroutine support with room
implementation("androidx.room:room-ktx:$room_version")

//kotlin extension for coroutine support with activities
implementation "androidx.activity:activity-ktx:$activityVersion"
//**

This is how it worked for me correctly

Comments

2

This is a version error. Try updating your room dependencies.

I changed mine from:implementation "androidx.room:room-runtime:2.2.5"

To :implementation "androidx.room:room-runtime:2.4.2"

Comments

1

In my case I tried to save to DB non-Entity objects. Then replaced with Entity class (contains @Entity(tableName = "your_table", indices = [Index("your_key")])).

Comments

1

I believe is that you have missed to give Entity annotation to T class. For example Reason class should have @Entity and give it to ReasonDao class. Like:

@Dao public abstract class ReasonDao extends BaseDao<Reason>{}

Comments

1

Do not replace kapt with annotationProcessor

Try this instead

def room_version = "2.5.1"

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

// To use Kotlin annotation processing tool (kapt)
kapt "androidx.room:room-compiler:$room_version"

// To use Coroutine features with room
implementation "androidx.room:room-ktx:$room_version"

Comments

0

What is missing here is the Data class. Generally, @Entity represents objects you want to store,

  • Room entity includes fields for each column inside the
  • table in the database
@Entity(tableName="something") data class YourData()
            

Comments

0

For those who has a "Type of the parameter must be a class annotated with @Entity or a collection/array of it " error when using Kotlin in the dao , you should try using @JvmSuppressWildcards annotation on your functions. eg.

 @Query("SELECT * FROM materials")
 @JvmSuppressWildcards
 fun getAllMaterials(): LiveData<List<MaterialModel>>

Comments

0

In my case I was trying to store a data class object into the Room Database. The error says that the parameter for Insert should be a class which has an annotation of @Entity so I created a table (entity) which has same values as data class and stored them successfully

Comments

0

One small mistake I did was I did not annotate my data class with the @Entity annotation

Table declaration

@Entity // Check if you have used this annotation or not
data class fooTable(){
...
}

In DAO

@Dao
interface myDao{
  @Insert
  suspend fun addFoo(fooObj: fooTable)
  }
}

If you are trying to insert a row in a table in Room DB then the corresponding data class should be annotated with @Entity annotation

Comments

0

Actually changing the version room matters too, like I changed my room version from 2.2.6 to 2.4.3 and it worked. if the Kotlin version is low it's better to use a lower version of the room as well if the Kotlin version is high it's better to use a higher version too.

Comments

0

In My case dependence version issue. I have upgreade dependence now working fine. so make sure dependence is according to kotlin version.

**def room_version = "2.5.1"**
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"

Comments

0

I had this issue when I accidentally used vararg inside the method:

@Insert
fun insertAll(vararg postDbModels: Array<PostDbModel>)

To fix this issue I just removed vararg and using an Array of @Entity class model instead:

@Insert
fun insertAll(postDbModels: Array<PostDbModel>)

Comments

0
implementation ("androidx.core:core-ktx:1.10.1")
implementation ("androidx.appcompat:appcompat:1.6.1")

implementation ("androidx.activity:activity-ktx:$activityVersion")

// Dependencies for working with Architecture components
// You'll probably have to update the version numbers in build.gradle (Project)

// Room components
implementation ("androidx.room:room-ktx:$roomVersion")
kapt ("androidx.room:room-compiler:$roomVersion")

androidTestImplementation ("androidx.room:room-testing:$roomVersion")

// Lifecycle components
implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")
implementation ("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion")
implementation ("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")

// Kotlin components
implementation ("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion")
api ("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines")
api ("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines")`

1 Comment

Please add a description text.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.