我正在使用 Room 架构组件来实现持久化。我创建了通用 DAO 接口以避免样板代码。 房间专业提示
但是我的代码无法编译并显示“错误:(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();
}
我这里有什么遗漏的吗? 它的工作原理如下这里
在 gradle 中对此进行了更改:
kapt "androidx.room:room-compiler:$roomVersion"
对此:
annotationProcessor "androidx.room:room-compiler:$room_version"
我最初遵循 Kotlin 中使用的方法,但这在 Java 代码中给出了错误。 两个快速更改为我解决了这个问题
请找到下面的代码,现在它可以正常运行了
@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();
}
如果您在 Kotlin 1.7.10+ 和 Room 中遇到此问题 < 2.4.2, upgrading Room to 2.4.3 fixes the issue.
来自 Room 2.4.3 的变更日志: 修复了导致 Room 无法识别 Kotlin 1.7 中的挂起函数的问题
此问题是由于在接口中使用
suspend
函数进行插入/删除造成的:
https://issuetracker.google.com/issues/236612358
问题是在我的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"
解决了!稍后谢谢我
原因是您指定了 ReasonDao 类型作为泛型参数,而不是 Reason。
原代码:
@Dao
public abstract class ReasonDao implements BaseDao<ReasonDao> {
...
}
正确代码:
@Dao
public abstract class ReasonDao implements BaseDao<Reason> {
...
}
其中 Reason 是用 @Entity 注释标记的类型。
顺便说一句,这已在接受的答案中修复,但在更改列表中未提及:)
在 gradle 中将此: kapt "androidx.room:room-compiler:$roomVersion" 更改为:annotationProcessor "androidx.room:room-compiler:$room_version"
执行此解决方案对我有部分帮助,但当尝试在数据库中插入日期时,它对我不起作用,因此尝试 kapt "androidx.room:room-compiler:$roomVersion" 并将 room_version 更改为最新的稳定版本https: //developer.android.com/jetpack/androidx/releases/room#groovy 附属项 {
//**
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"
//**
这对我来说是正确的工作方式
这是版本错误。尝试更新您的房间依赖项。
我将我的更改为:
implementation "androidx.room:room-runtime:2.2.5"
致:
implementation "androidx.room:room-runtime:2.4.2"
去掉暂停就可以了。
@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)
}
就我而言,我尝试保存到数据库非实体对象。然后替换为实体类(包含
@Entity(tableName = "your_table", indices = [Index("your_key")])
)。
我相信您错过了为 T 类提供
Entity
注释。例如 Reason
类应该有 @Entity
并将其交给 ReasonDao 类。喜欢:
@Dao
public abstract class ReasonDao extends BaseDao<Reason>{}
请勿将
kapt
替换为 annotationProcessor
试试这个吧
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"
这里缺少的是 Data 类。一般来说, @Entity代表你要存储的对象,
- 房间实体包含
内每列的字段- 数据库中的表
@Entity(tableName="something") data class YourData()
对于那些在 dao 中使用 Kotlin 时遇到“参数类型必须是用 @Entity 注释的类或其集合/数组”错误的人,您应该尝试在函数上使用 @JvmSuppressWildcards 注释。例如。
@Query("SELECT * FROM materials")
@JvmSuppressWildcards
fun getAllMaterials(): LiveData<List<MaterialModel>>
在我的例子中,我试图将数据类对象存储到房间数据库中。该错误表明
Insert
的参数应该是一个具有 @Entity
注释的类,因此我创建了一个与数据类具有相同值的表(实体)并成功存储了它们
我犯的一个小错误是 我没有使用 @Entity 注释来注释我的数据类
表声明
@Entity // Check if you have used this annotation or not
data class fooTable(){
...
}
在 DAO 中
@Dao
interface myDao{
@Insert
suspend fun addFoo(fooObj: fooTable)
}
}
如果您尝试在 Room DB 的表中插入一行,则应使用 @Entity 注释来注释相应的数据类
实际上更改版本房间也很重要,就像我将房间版本从 2.2.6 更改为 2.4.3 并且它有效。如果 Kotlin 版本低,最好也使用较低版本的 Room;如果 Kotlin 版本高,最好也使用较高版本。
就我而言,依赖版本问题。我已经升级依赖现在工作正常。 因此请确保依赖关系符合 kotlin 版本。
**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"
当我在方法中不小心使用vararg时遇到了这个问题:
@Insert
fun insertAll(vararg postDbModels: Array<PostDbModel>)
为了解决这个问题,我刚刚删除了 vararg 并使用 @Entity 类模型数组代替:
@Insert
fun insertAll(postDbModels: Array<PostDbModel>)