【问题标题】:How to resolve "Entities and POJOs must have a usable public constructor"如何解决“实体和 POJO 必须具有可用的公共构造函数”
【发布时间】:2021-12-25 17:30:41
【问题描述】:

我在 SO 上看到过这个问题several 次。但是该解决方案似乎不适用于我的问题。

我有一个 Kotlin 数据类,用作 Room 中的实体

@Entity(tableName = "training_session")
data class SessionEntity(
    @PrimaryKey(autoGenerate = false) val id: Long,
    @ColumnInfo(name = "current_state_marker") val currentState: Short,
    @Embedded val states: List<Int>
)

它正在生产

> Task :training-infrastructure:kaptDebugKotlin FAILED
error: Entities and POJOs must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type). - java.util.List
error: Entities and POJOs must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type). - java.util.List

在同一个项目中,我有一个非常相似的实体,它也有一个列表并且不会产生任何错误。


尝试了MikeT 提供的答案,对我来说它需要一个小的change 以定义转换器的方式

data class SessionStateList (val stateList : List<Int>) 

class SessionStateListConverter {

    @TypeConverter
    fun fromArraySessionStateList(sh: List<Int>?): String? {
        return Gson().toJson(sh)
    }
    @TypeConverter
    fun toArraySessionStateList(sh: String?): List<Int>? {
        val listType: Type = object : TypeToken<ArrayList<Int?>?>() {}.type
        return Gson().fromJson(sh,listType)
    }
}

快速跟进。我曾提到我有另一个实体具有 Embedded val something: List&lt;Int&gt;,但我没有注意到任何编译器错误。

我没有注意到任何编译器错误的原因是该实体未包含在@Database 注释中。

【问题讨论】:

  • 对即时错误的简单修复可能是使用ArrayListList 是一个接口,没有构造函数。 “错误:实体 .. 必须有一个可用的公共构造函数 .. - java.util.List”
  • 您是否在RoomDatabase 上注册了一个TypeConverter,可以将List&lt;Int&gt; 转换为Room 可以使用的东西?
  • 虽然达到“最终目标”可能涉及一些映射以将列表有意义地关联到 SQL 表。请参阅stackoverflow.com/questions/44986626/…
  • @user2864740 - 好点 - 这让我逃脱了,但改变它会产生另一个问题“错误:找不到字段的设置器。 - java.util.ArrayList 中的大小”。此外,您提供的链接被证明有助于映射数组 - 谢谢

标签: android kotlin android-room


【解决方案1】:

您不能将列表/数组等作为列类型。所以你的问题集中在@Embedded val states: List&lt;Int&gt;

你可以有一个 POJO,例如状态持有者:-

data class StatesHolder(
    val stateList: List<Int>
)

然后有

@Entity(tableName = "training_session")
data class SessionEntity(
    @PrimaryKey(autoGenerate = false) val id: Long,
    @ColumnInfo(name = "current_state_marker") val currentState: Short,
    val states: StatesHolder
)
  • 请注意,您不能嵌入 StatesHolder,因为那只是插入列表。如果要嵌入,则必须嵌入使用 StatesHolder 的包装器。

然后,您将需要 TypeConverters 来将 StatesHolder 对象转换为可存储的类型。可能是一个字符串,也可能是 StatesHold 对象的 JSON 表示,例如

class Converters {

    @TypeConverter
    fun fromStatesHolder(sh: StatesHolder): String {
        return Gson().toJson(sh)
    }
    @TypeConverter
    fun toStatesHolder(sh: String): StatesHolder {
        return Gson().fromJson(sh,StatesHolder::class.java)
    }
}

您还需要使用定义 Converts::class 的 @TypeConverters 注解。如果在 @Database 级别编码,则转换器具有完整范围。

所以在@Database(.....) 之后,你可以:-

@TypeConverters(Converters::class)

【讨论】:

    猜你喜欢
    • 2021-05-01
    • 2020-08-12
    • 1970-01-01
    • 2020-09-03
    • 2020-10-31
    • 2019-09-14
    • 2018-06-24
    • 2017-11-20
    • 2019-05-21
    相关资源
    最近更新 更多