【问题标题】:How to fix Entities and POJOs must have a usable public constructor如何修复实体和 POJO 必须有可用的公共构造函数
【发布时间】:2020-08-12 07:15:29
【问题描述】:

当我尝试在使用 sqlite 数据库时启动我的应用程序时遇到此错误。

我在单独的文件中有 3 个数据类:

@Entity(tableName = "movies")
data class MovieNews(
    @PrimaryKey(autoGenerate = true)
    var id: Int? = null,
    @SerializedName("movie_db")
    @Embedded(prefix = "movies_")
    val movies: List<Movies>? = null,
)

data class Movies(
    val description: String? = null,
    @Embedded(prefix = "actors_")
    val actors: List<Actors>? = null,

)

data class Actors(
    val name: String? = null
    val age: Int? = null
)

当我启动应用程序时出现错误:

错误:实体和 POJO 必须具有可用的公共构造函数。你 可以有一个空的构造函数或参数匹配的构造函数 字段(按名称和类型)。 - java.util.List

如何解决此错误?

不知道这是否与问题有关,但我有这个警告

w: [kapt] 请求增量注释处理,但是 支持被禁用,因为以下处理器不是 增量:androidx.room.RoomProcessor (DYNAMIC)。

我也看到了很多关于这个错误的问题,没有一个能解决我的问题

更新:

如果我注释掉 Embedded 行,应用程序会编译。

我深入研究了 stackoverflow 问题,发现Embedded 和列表可能存在问题。

   @SerializedName("movie_db")
    @Embedded(prefix = "movies_")
    val movies: List<Movies>? = null,

【问题讨论】:

    标签: android sqlite kotlin


    【解决方案1】:

    一般情况:

    data class MyDataClass(
      var myfield: String
    ){
      constructor(myfield: String): this(myfield)
    }
    

    对于您的数据类:只需在构造函数中提供一个默认值即可:

    @Entity(tableName = "movies")
    data class MovieNews(
        @PrimaryKey(autoGenerate = true)
        var id: Int? = null,
        @SerializedName("movie_db")
        @Embedded(prefix = "movies_")
        val movies: List<Movies>? = null,
    ){
      constructor(): this(0, "", listOf())
    }
    
    data class Movies(
        val description: String? = null,
        @Embedded(prefix = "actors_")
        val actors: List<Actors>? = null,
    ) // same
    
    data class Actors(
        val name: String? = null
        val age: Int? = null
    ) //same
    

    为什么会这样?因为 Room 不知道如何告诉 Java 生成的代码如何初始化空字段(Java 不支持默认值)

    如果您不喜欢该解决方案:只需删除 ? 并将所有内容设为 val 但提供默认值。

    第二件事与您的问题无关,但可以通过添加来解决:

    javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [
                            "room.schemaLocation"  : "$projectDir/schemas".toString(),
                            "room.incremental"     : "true",
                            "room.expandProjection": "true"]
                }
            }
    

    在你的build.gradle

    【讨论】:

    • 感谢您的详细回答,但不幸的是,没有一个答案对我有用。查看我关于嵌入式线路的更新,也许它可以为您指明正确的方向
    • 这篇文章有帮助吗? coroutinedispatcher.com/2019/08/…
    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 2021-05-01
    • 2020-09-03
    • 2019-09-14
    • 2020-10-31
    • 2018-06-24
    • 2017-11-20
    • 2019-05-21
    相关资源
    最近更新 更多