"Type of the parameter must be a class annotated with @Entity" while creating Generic DAO interface in Room
Asked Answered
M

19

41

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

Marquis answered 28/12, 2017 at 22:42 Comment(3)
where is your data class?Roi
did you find the solution?Millikan
Yes, the accepted answer worked for me.Marquis
M
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();

  }
Marquis answered 29/12, 2017 at 5:30 Comment(1)
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.Tetrarch
H
71

Changed in gradle from this:

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

to this:

annotationProcessor "androidx.room:room-compiler:$room_version"
Hulky answered 15/10, 2021 at 18:46 Comment(5)
This one solved mine!Becca
that is the solution for me, but why? I added kapt in plugins !Hamhung
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: https://mcmap.net/q/385761/-quot-type-of-the-parameter-must-be-a-class-annotated-with-entity-quot-while-creating-generic-dao-interface-in-roomChoking
instead of doing this add the "ktx" compiler implementation "androidx.room:room-ktx:$android_room" instead and leave kapt aloneCutlerr
This solve my problem and save my day. ThanksGlynda
M
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();

  }
Marquis answered 29/12, 2017 at 5:30 Comment(1)
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.Tetrarch
J
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

Jehoshaphat answered 10/8, 2022 at 10:33 Comment(1)
Solved the error for meGranuloma
S
7

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)

}
Staffan answered 21/8, 2022 at 5:12 Comment(0)
H
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

Hadron answered 30/10, 2021 at 13:58 Comment(1)
That works for me also.Vermin
R
5

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 :)

Radiotherapy answered 19/12, 2018 at 20:16 Comment(0)
S
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

Stricture answered 21/12, 2021 at 18:1 Comment(0)
R
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"

Rebba answered 23/5, 2022 at 10:54 Comment(0)
P
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")])).

Pignut answered 23/4, 2018 at 18:11 Comment(0)
P
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>{}

Presidio answered 4/5, 2018 at 9:59 Comment(0)
H
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"
Halpin answered 7/4, 2023 at 18:37 Comment(0)
N
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()
            
Nonparous answered 24/5, 2021 at 4:31 Comment(0)
P
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>>
Palatable answered 28/9, 2021 at 8:17 Comment(0)
J
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

Jea answered 6/9, 2022 at 16:44 Comment(0)
V
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

Vinitavinn answered 9/9, 2022 at 13:24 Comment(0)
I
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.

Instar answered 5/12, 2022 at 9:7 Comment(0)
C
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"
Cracknel answered 14/6, 2023 at 2:28 Comment(0)
L
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>)
Leapfrog answered 5/8, 2023 at 10:39 Comment(0)
S
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")`
Springer answered 17/10, 2023 at 20:57 Comment(1)
Please add a description text.Parhe

© 2022 - 2024 — McMap. All rights reserved.