房间: "类型转换器的返回类型无效"

3

我有一个Room数据库,其中包含以下实体:

data class NoteEntity(
    val startRef: BibleRef,
    val endRef: BibleRef,
    val content: String
)

我添加了以下类型转换器,将BibleRef字段存储为整数:
class Converters {
    @TypeConverter
    fun bibleRefToInt(ref: BibleRef?): Int? {
        // performs conversion...
    }

    @TypeConverter
    fun bibleRefFromInt(refInt: Int?): BibleRef? {
        // performs conversion...
    }
}

我遇到了以下构建错误(使用 kapt):
Invalid return type for a type converter. - Converters.bibleRefFromInt(java.lang.Integer)

BibleRef 是一个简单的 Kotlin 数据类。

data class BibleRef(
    val book: Int,
    val chapter: Int,
    val verse: Int
)
1个回答

1

您似乎没有包含@TypeConverters注释。

  • 请注意使用复数形式 (定义 TypeConverters 所在的类) 而不是单数形式 (将方法/函数定义为 TypeConverter)

对于您的情况,应该是:

@TypeConverters(Converters::class)

建议将它编码在具有@Database注释的类中,该注释可以紧接着或者在@Database注释之后,例如:

@TypeConverters(Converters::class)
@Database(entities = [NoteEntity::class], version = 1)

这提供了最广泛的范围。

用于验证上述内容的完整代码:

BibleRef(未更改)

data class BibleRef(
    val book: Int,
    val chapter: Int,
    val verse: Int
)

NoteEntity(参见注释)

@Entity
data class NoteEntity(
    @PrimaryKey
    val id: Long? = null,
    val startRef: BibleRef,
    val endRef: BibleRef,
    val content: String
)
  • 添加id列作为主键,否则会出现错误:error: An entity must have at least 1 field annotated with @PrimaryKey public final class NoteEntity {

  • 添加@Entity注释,否则会出现错误:error: Entity class must be annotated with @Entity public final class NoteEntity {

转换器(请参阅说明)

class Converters {
    @TypeConverter
    fun bibleRefToInt(ref: BibleRef?): Int? {
        return 0
    }

    @TypeConverter
    fun bibleRefFromInt(ref: Int?): BibleRef? {
        return BibleRef(0,0,0)
    }
}
  • 两者都改为返回适当类型的值。

TheDatabase添加,以便对Room代码进行完整编译并生成生成的Java代码。

@TypeConverters(Converters::class)
@Database(entities = [NoteEntity::class], version = 1)
abstract class TheDatabase: RoomDatabase() {
}
  • 请注意,未使用任何@Dao注释的类。

构建日志:

Executing tasks: [:app:assembleDebug] in project E:\AndroidStudioApps\SO70425430KotlinRoomTypeConverterInvalidReturnType

> Task :app:preBuild UP-TO-DATE
> Task :app:preDebugBuild UP-TO-DATE
> Task :app:compileDebugAidl NO-SOURCE
> Task :app:compileDebugRenderscript NO-SOURCE
> Task :app:generateDebugBuildConfig UP-TO-DATE
> Task :app:checkDebugAarMetadata UP-TO-DATE
> Task :app:generateDebugResValues UP-TO-DATE
> Task :app:generateDebugResources UP-TO-DATE
> Task :app:mergeDebugResources UP-TO-DATE
> Task :app:createDebugCompatibleScreenManifests UP-TO-DATE
> Task :app:extractDeepLinksDebug UP-TO-DATE
> Task :app:processDebugMainManifest UP-TO-DATE
> Task :app:processDebugManifest UP-TO-DATE
> Task :app:processDebugManifestForPackage UP-TO-DATE
> Task :app:processDebugResources UP-TO-DATE
> Task :app:kaptGenerateStubsDebugKotlin
> Task :app:javaPreCompileDebug UP-TO-DATE
> Task :app:mergeDebugNativeDebugMetadata NO-SOURCE
> Task :app:mergeDebugShaders UP-TO-DATE
> Task :app:compileDebugShaders NO-SOURCE
> Task :app:generateDebugAssets UP-TO-DATE
> Task :app:mergeDebugAssets UP-TO-DATE
> Task :app:compressDebugAssets UP-TO-DATE
> Task :app:processDebugJavaRes NO-SOURCE
> Task :app:checkDebugDuplicateClasses UP-TO-DATE
> Task :app:desugarDebugFileDependencies UP-TO-DATE
> Task :app:mergeExtDexDebug UP-TO-DATE
> Task :app:mergeLibDexDebug UP-TO-DATE
> Task :app:mergeDebugJniLibFolders UP-TO-DATE
> Task :app:mergeDebugNativeLibs NO-SOURCE
> Task :app:stripDebugDebugSymbols NO-SOURCE
> Task :app:validateSigningDebug UP-TO-DATE
> Task :app:writeDebugAppMetadata UP-TO-DATE
> Task :app:writeDebugSigningConfigVersions UP-TO-DATE

> Task :app:kaptDebugKotlin
E:\AndroidStudioApps\SO70425430KotlinRoomTypeConverterInvalidReturnType\app\build\tmp\kapt3\stubs\debug\a\a\so70425430kotlinroomtypeconverterinvalidreturntype\TheDatabase.java:8: warning: Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide `room.schemaLocation` annotation processor argument OR set exportSchema to false.
public abstract class TheDatabase extends androidx.room.RoomDatabase {
                ^

> Task :app:compileDebugKotlin
w: E:\AndroidStudioApps\SO70425430KotlinRoomTypeConverterInvalidReturnType\app\src\main\java\a\a\so70425430kotlinroomtypeconverterinvalidreturntype\Converters.kt: (9, 23): Parameter 'ref' is never used
w: E:\AndroidStudioApps\SO70425430KotlinRoomTypeConverterInvalidReturnType\app\src\main\java\a\a\so70425430kotlinroomtypeconverterinvalidreturntype\Converters.kt: (14, 25): Parameter 'ref' is never used

> Task :app:compileDebugJavaWithJavac
> Task :app:compileDebugSources
> Task :app:mergeDebugJavaResource UP-TO-DATE
> Task :app:dexBuilderDebug
> Task :app:mergeProjectDexDebug
> Task :app:packageDebug
> Task :app:assembleDebug

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/7.0.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 2s
30 actionable tasks: 7 executed, 23 up-to-date

Build Analyzer results available

抱歉,实际上我在我的代码中包含了这个部分(并且正如您建议的那样,在数据库中也是如此)。只是为了简洁起见,在我的帖子中省略了这一部分。 - Matt Robertson
@MattRobertson 那么问题就在于你没有提供其他代码,因为你提供的上述代码已经包含了适当的附加代码,即 NoteEntity 类的 @Entity 注释和简单的代码来替换 // performs conversion...(即 toInt 返回 Int 和 fromInt 返回 BibleRef),这样编译就会成功。 - MikeT
我同意,我只是不确定还有什么其他原因会导致这成为“无效的返回类型”。 - Matt Robertson
@MattRobertson 我会编辑答案以显示编译的代码,然后将其应用到其他代码中,直到问题浮现。个人而言,我经常编译Room。 - MikeT
我已经解决了这个问题。我仍然不知道是什么原因导致的,但可能是缓存损坏的问题。我隐藏了(然后删除了)这些更改,然后以完全相同的方式重新实现它们,现在完全相同的代码可以工作了。将此答案标记为正确。 - Matt Robertson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接