Room - 不确定如何将 Cursor 转换为该方法的返回类型 (java.lang.Object)

问题描述 投票:0回答:1

我正在使用 Room 创建一个项目,并且有以下代码:

对于我的实体类:

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity("matches")
data class MatchEntity(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int,
    @ColumnInfo(name = "name") val name: String,
    @ColumnInfo(name = "city") val city: String,
    @ColumnInfo(name = "distance") val distance: Int,
    @ColumnInfo(name = "description") val description: String,
    @ColumnInfo(name = "score") val score: Int,
    @ColumnInfo(name = "age") val age: Int,
    @ColumnInfo(name = "body_type") val bodyType: BodyType,
    @ColumnInfo(name = "height") val height: Float,
    @ColumnInfo(name = "diet") val diet: DietType,
    @ColumnInfo(name = "zodiac_sign") val zodiacSign: ZodiacSign,
    @ColumnInfo(name = "religion") val religion: Religion,
    @ColumnInfo(name = "drinking_habit") val drinkingHabit: DrinkingHabit,
    @ColumnInfo(name = "smoking_habit") val smokingHabit: SmokingHabit,
    @ColumnInfo(name = "mbti_type") val mbtiType: MbtiType,
    @ColumnInfo(name = "enneagram") val enneagram: Enneagram,
    @ColumnInfo(name = "kids_type") val kidsType: KidsType,
)

对于我的 DAO 课程:

@Dao
interface MatchDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(matchEntity: MatchEntity): Long

    @Update
    suspend fun update(matchEntity: MatchEntity): Int

    @Delete
    suspend fun delete(matchEntity: MatchEntity)

    @Query("SELECT * FROM matches")
    suspend fun getAll(): List<MatchEntity>

    @Query("SELECT * FROM matches WHERE id = :id")
    suspend fun getById(id: Int): List<MatchEntity>
}

对于我的 RoomDatabase 类:

@Suppress("TooManyFunctions")
@Database(
    entities = [
        MatchEntity::class, MatchIceBreakerEntity::class, MatchInterestEntity::class,
        MatchScheduleEntity::class, MatchSocialEntity::class, MatchStoryEntity::class,
        UserEntity::class, UserIceBreakerEntity::class, UserInterestEntity::class,
        UserSocialEntity::class, UserStoryEntity::class
    ],
    exportSchema = false,
    version = 1
)
@TypeConverters(
    BodyTypeConverter::class,
    DietTypeConverter::class,
    DrinkingHabitConverter::class,
    EnneagramConverter::class,
    KidsTypeConverter::class,
    MbtiTraitConverter::class,
    MbtiTypeConverter::class,
    ReligionConverter::class,
    SleepingHabitConverter::class,
    SmokingHabitConverter::class,
    SocialConverter::class,
    SocialMediaFrequencyConverter::class,
    WorkoutTypeConverter::class,
    ZodiacSignConverter::class
)
abstract class WingmanDatabase : RoomDatabase() {

    abstract fun matchDao(): MatchDao
    abstract fun matchIceBreakerDao(): MatchIceBreakerDao
    abstract fun matchInterestDao(): MatchInterestDao
    abstract fun matchScheduleDao(): MatchScheduleDao
    abstract fun matchSocialDao(): MatchSocialDao
    abstract fun matchStoryDao(): MatcStoryDao
    abstract fun userDao(): UserDao
    abstract fun userIceBreakerDao(): UserIceBreakerDao
    abstract fun userInterestDao(): UserInterestDao
    abstract fun userSocialDao(): UserSocialDao
    abstract fun userStoryDao(): UserStoryDao

    companion object {
        const val DATABASE_NAME: String = "wingman_db"
    }
}

对于我的依赖:

plugins {
    ...
    
    id 'kotlin-kapt'
}

...

android {

    ...

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }

...

dependencies {

    ...

    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"
}

对于我的 build.gradle 插件:

plugins {
    id 'com.android.application' version '8.0.1' apply false
    id 'com.android.library' version '8.0.1' apply false
    id 'androidx.navigation.safeargs' version '2.5.3' apply false
    id 'org.jetbrains.kotlin.android' version '1.9.0-Beta' apply false
}

我已经与 Room 合作了很多次,但不知何故,这次我遇到了这个错误:

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:27: error: Not sure how to convert a Cursor to this method's return type (java.lang.Object).
    public abstract java.lang.Object getAll(@org.jetbrains.annotations.NotNull

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:28: error: Query method parameters should either be a type that can be converted into a database column or a List / Array that contains such type. You can consider adding a Type Adapter for this.
    kotlin.coroutines.Continuation<? super java.util.List<com.hikarisource.wingman.data.local.entity.MatchEntity>> $completion);

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:27: error: Unused parameter: $completion
    public abstract java.lang.Object getAll(@org.jetbrains.annotations.NotNull

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:32: error: Not sure how to convert a Cursor to this method's return type (java.lang.Object).
    public abstract java.lang.Object getById(int id, @org.jetbrains.annotations.NotNull

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:33: error: Query method parameters should either be a type that can be converted into a database column or a List / Array that contains such type. You can consider adding a Type Adapter for this.
    kotlin.coroutines.Continuation<? super java.util.List<com.hikarisource.wingman.data.local.entity.MatchEntity>> $completion);

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:32: error: Unused parameter: $completion
    public abstract java.lang.Object getById(int id, @org.jetbrains.annotations.NotNull

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:11: error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
    kotlin.coroutines.Continuation<? super java.lang.Long> $completion);

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:9: error: Not sure how to handle insert method's return type.
    public abstract java.lang.Object insert(@org.jetbrains.annotations.NotNull

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:21: error: Not sure how to handle delete method's return type. Currently the supported return types are void, int or Int.
    public abstract java.lang.Object delete(@org.jetbrains.annotations.NotNull

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:23: error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
    kotlin.coroutines.Continuation<? super kotlin.Unit> $completion);

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:17: error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
    kotlin.coroutines.Continuation<? super java.lang.Integer> $completion);

C:\Users\Leona\workspace\wingman\app\build\tmp\kapt3\stubs\debug\com\hikarisource\wingman\data\local\dao\MatchDao.java:15: error: Not sure how to handle update method's return type. Currently the supported return types are void, int or Int.
    public abstract java.lang.Object update(@org.jetbrains.annotations.NotNull

这是由 MatchDao 生成的代码:

@kotlin.Metadata(mv = {1, 9, 0}, k = 1, xi = 48, d1 = {"\u00000\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010 \n\u0002\b\u0003\n\u0002\u0010\b\n\u0002\b\u0002\n\u0002\u0010\t\n\u0002\b\u0002\bg\u0018\u00002\u00020\u0001J\u0019\u0010\u0002\u001a\u00020\u00032\u0006\u0010\u0004\u001a\u00020\u0005H\u00a7@\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0006J\u0017\u0010\u0007\u001a\b\u0012\u0004\u0012\u00020\u00050\bH\u00a7@\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\tJ\u001f\u0010\n\u001a\b\u0012\u0004\u0012\u00020\u00050\b2\u0006\u0010\u000b\u001a\u00020\fH\u00a7@\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\rJ\u0019\u0010\u000e\u001a\u00020\u000f2\u0006\u0010\u0004\u001a\u00020\u0005H\u00a7@\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0006J\u0019\u0010\u0010\u001a\u00020\f2\u0006\u0010\u0004\u001a\u00020\u0005H\u00a7@\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0006\u0082\u0002\u0004\n\u0002\b\u0019\u00a8\u0006\u0011"}, d2 = {"Lcom/hikarisource/wingman/data/local/dao/MatchDao;", "", "delete", "", "matchEntity", "Lcom/hikarisource/wingman/data/local/entity/MatchEntity;", "(Lcom/hikarisource/wingman/data/local/entity/MatchEntity;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", "getAll", "", "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", "getById", "id", "", "(ILkotlin/coroutines/Continuation;)Ljava/lang/Object;", "insert", "", "update", "app_debug"})
@androidx.room.Dao
public abstract interface MatchDao {
    
    @androidx.room.Insert(onConflict = 1)
    @org.jetbrains.annotations.Nullable
    public abstract java.lang.Object insert(@org.jetbrains.annotations.NotNull
    com.hikarisource.wingman.data.local.entity.MatchEntity matchEntity, @org.jetbrains.annotations.NotNull
    kotlin.coroutines.Continuation<? super java.lang.Long> $completion);
    
    @androidx.room.Update
    @org.jetbrains.annotations.Nullable
    public abstract java.lang.Object update(@org.jetbrains.annotations.NotNull
    com.hikarisource.wingman.data.local.entity.MatchEntity matchEntity, @org.jetbrains.annotations.NotNull
    kotlin.coroutines.Continuation<? super java.lang.Integer> $completion);
    
    @androidx.room.Delete
    @org.jetbrains.annotations.Nullable
    public abstract java.lang.Object delete(@org.jetbrains.annotations.NotNull
    com.hikarisource.wingman.data.local.entity.MatchEntity matchEntity, @org.jetbrains.annotations.NotNull
    kotlin.coroutines.Continuation<? super kotlin.Unit> $completion);
    
    @androidx.room.Query(value = "SELECT * FROM matches")
    @org.jetbrains.annotations.Nullable
    public abstract java.lang.Object getAll(@org.jetbrains.annotations.NotNull
    kotlin.coroutines.Continuation<? super java.util.List<com.hikarisource.wingman.data.local.entity.MatchEntity>> $completion);
    
    @androidx.room.Query(value = "SELECT * FROM matches WHERE id = :id")
    @org.jetbrains.annotations.Nullable
    public abstract java.lang.Object getById(int id, @org.jetbrains.annotations.NotNull
    kotlin.coroutines.Continuation<? super java.util.List<com.hikarisource.wingman.data.local.entity.MatchEntity>> $completion);
}

我将表的名称更改为

martches
而不是
match
,因为显然它不理解
match
是保留关键字。

另外,我尝试看看我的注释是否有错误,但我找不到它。

我还尝试从所有 DAO 中删除

suspend
,尽管我不再出现编译时错误,但我开始在运行时出现错误:

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

如果有人知道发生了什么事,我将不胜感激帮助:)

android sqlite kotlin android-room
1个回答
0
投票

解决方案是删除

suspend
修饰符。显然,即使返回类型不是像 LiveData 或 Flow 这样的 DataStream,Room 也放弃了它的使用。

现在我的 DAO 类看起来像这样:

@Dao
interface MatchDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(matchEntity: MatchEntity): Long

    @Update
    fun update(matchEntity: MatchEntity): Int

    @Delete
    fun delete(matchEntity: MatchEntity)

    @Query("SELECT * FROM matches")
    fun getAll(): List<MatchEntity>

    @Query("SELECT * FROM matches WHERE id = :id")
    fun getById(id: Int): List<MatchEntity>
}

请小心,因为你不应该在主线程上调用它,所以不要忘记将你的调度程序更改为 IO。

© www.soinside.com 2019 - 2024. All rights reserved.