在Room中创建Generic DAO接口时,"参数的类型必须是使用@Entity注释的类"

Dee*_*haV 9 java android persistence dao android-room

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

但是我的代码没有编译说"Error:(21,19)error:参数的类型必须是用@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();

}
Run Code Online (Sandbox Code Playgroud)

这里有什么我想念的吗?它是这样工作在这里

小智 68

Changed in gradle from this:

kapt "androidx.room:room-compiler:$roomVersion"
Run Code Online (Sandbox Code Playgroud)

to this:

annotationProcessor "androidx.room:room-compiler:$room_version"
Run Code Online (Sandbox Code Playgroud)


Shi*_*ath 11

如果您在 Kotlin 1.7.10+ 和 Room < 2.4.2 中遇到此问题,将 Room 升级到 2.4.3 可以修复该问题。

来自 Room 2.4.3 的变更日志:修复了导致 Room 无法识别 Kotlin 1.7 中的挂起函数的问题

此问题是由于suspend在接口中使用插入/删除函数造成的: https://issuetracker.google.com/issues/236612358


Dee*_*haV 6

我最初遵循 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();

  }
Run Code Online (Sandbox Code Playgroud)


小智 6

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

\n
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.0"\n
Run Code Online (Sandbox Code Playgroud)\n

但据我了解,这个版本的 Kotlin 以及 Room 和协程不能很好地工作\xe2\x80\x99。\n能够通过将 Kotlin 版本降级到以下来解决该问题:

\n
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.32"\n
Run Code Online (Sandbox Code Playgroud)\n

解决了!晚点再谢我

\n


Une*_*eXp 5

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

原始代码:

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

   ...

}
Run Code Online (Sandbox Code Playgroud)

正确代码:

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

   ...

}
Run Code Online (Sandbox Code Playgroud)

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

顺便说一句,这在已接受的答案中已修复,但在更改列表中未提及:)


小智 5

删除暂停,然后它就可以工作了。

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

}
Run Code Online (Sandbox Code Playgroud)