在 Room 中创建通用 DAO 接口时,“参数的类型必须是带有 @Entity 注释的类”

Posted

技术标签:

【中文标题】在 Room 中创建通用 DAO 接口时,“参数的类型必须是带有 @Entity 注释的类”【英文标题】:"Type of the parameter must be a class annotated with @Entity" while creating Generic DAO interface in Room 【发布时间】:2018-06-09 11:05:36 【问题描述】:

我正在使用 Room 架构组件来实现持久性。我创建了通用 DAO 接口以避免样板代码。 Room Pro Tips

但我的代码无法编译并显示“错误:(21, 19) 错误:参数的类型必须是使用 @Entity 注释的类或其集合/数组。”对于通用类 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();


这里有什么我想念的吗? 它就像这样here

【问题讨论】:

你的数据类在哪里? 你找到解决办法了吗? 是的,接受的答案对我有用。 【参考方案1】:

从这里改变了 gradle:

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

到这里:

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

【讨论】:

【参考方案2】:

我最初遵循 Kotlin 中使用的方法,但这会在 Java 代码中出现错误。 两个快速更改为我修复了它

将 BaseDao 更改为抽象类 为 BaseDao 添加了@Dao 注解

请找到下面的代码,现在它可以正常运行了

@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();

  

【讨论】:

您好,根据我的经验。当您收到此类错误时,请尝试注释所有方法并依次取消注释每个方法并每次重新构建。【参考方案3】:

原因是您将 ReasonDao 类型指定为泛型参数,而不是 Reason

原码:

@Dao
public abstract class ReasonDao implements BaseDao<ReasonDao> 

   ...


正确代码:

@Dao
public abstract class ReasonDao implements BaseDao<Reason> 

   ...


其中 Reason 是标有 @Entity 注释的类型。

顺便说一句,这在接受的答案中是固定的,但在更改列表中没有提到:)

【讨论】:

【参考方案4】:

问题是在我的 build.gradle 中,我使用的 Kotlin 版本是 1.5.0

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

但据我了解,这个版本的 Kotlin 以及 Room 和协程并不能很好地工作。 能够通过将 Kotlin 版本降级为:

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

解决了!稍后谢谢我

【讨论】:

这也适用于我。【参考方案5】:

在我的情况下,我尝试保存到 DB 非实体对象。然后替换为Entity类(包含@Entity(tableName = "your_table", indices = [Index("your_key")]))。

【讨论】:

【参考方案6】:

我相信你错过了给 T 类注解Entity。例如 Reason 类应该有 @Entity 并将其提供给 ReasonDao 类。喜欢:

@Dao public abstract class ReasonDao extends BaseDao<Reason>

【讨论】:

【参考方案7】:

在 gradle 中更改了这个:kapt "androidx.room:room-compiler:$roomVersion" 到这个:annotationProcessor "androidx.room:room-compiler:$room_version"

执行此解决方案部分为我服务,但尝试在数据库中插入日期时它对我不起作用,因此请尝试 kapt "androidx.room:room-compiler:$roomVersion" 并将 room_version 更改为最新的稳定版本 @ 987654321@ 附件

//**
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"
//**

这对我来说是正确的

【讨论】:

【参考方案8】:

这里缺少的是 Data 类。一般来说, @Entity 代表你要存储的对象,

房间实体包括每个列的字段 数据库中的表
@Entity(tableName="something") data class YourData()
            

【讨论】:

【参考方案9】:

对于那些在 dao 中使用 Kotlin 时出现“参数类型必须是使用 @Entity 注释的类或其集合/数组”的错误,您应该尝试在函数上使用 @JvmSuppressWildcards 注释。例如。

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

【讨论】:

以上是关于在 Room 中创建通用 DAO 接口时,“参数的类型必须是带有 @Entity 注释的类”的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PHP 中创建通用 DAO 接口?

Android Room 通用 DAO

在房间中创建表格的方法[重复]

如何在 Spring MVC 中的不同类中创建动态 bean

在 PHP 中创建 DAO 的正确方法

Room:来自 Dao 的 LiveData 将在每次更新时触发 Observer.onChanged,即使 LiveData 值没有变化