将Kotlin内联类作为实体字段的会议室数据库

时间:2019-10-02 14:48:08

标签: android kotlin android-room kotlin-experimental

我试图按照https://developer.android.com/topic/libraries/architecture/room中所述,使Room(Jake Whartons article Inline Classes Make Great Database IDs)与Kotlin的内联类一起工作:

@Entity
data class MyEntity(
    @PrimaryKey val id: ID,
    val title: String
)

inline class ID(val value: String)

编译此会议室时抱怨

  

实体和Pojos必须具有可用的公共构造函数。你可以有   一个空的构造函数或参数与之匹配的构造函数   字段(按名称和类型)。

查看生成的Java代码:

private MyEntity(String id, String title) {
      this.id = id;
      this.title = title;
}

// $FF: synthetic method
public MyEntity(String id, String title, DefaultConstructorMarker $constructor_marker) {
      this(id, title);
}

神秘地,默认构造函数现在是私有的。

当使用String作为id(或typealias)的类型时,生成的Java类构造函数看起来像预期的那样:

public MyEntity(@NotNull String id, @NotNull String title) {
  Intrinsics.checkParameterIsNotNull(id, "id");
  Intrinsics.checkParameterIsNotNull(title, "title");
  super();
  this.id = id;
  this.title = title;
}

现在有人在将内联类用作数据实体属性时如何使默认构造函数公开吗?

2 个答案:

答案 0 :(得分:0)

我相信原因是ID类在运行时将表示为String。因此,$ constructor_marker附加参数是为了保证MyEntity(String id,String title)构造函数签名的唯一性,因为可能已经定义了该构造函数。但我只是在推测。

您能否尝试在MyEntity类中显式定义此构造函数,并查看其是否有效?

答案 1 :(得分:0)

Kotlin 内联类使用名称修饰。

所以我相信您的 Room 数据库无法为您的 ID 字段找到 getter 和 setter。 尝试添加:

...
@get:JvmName("getID")
@set:JvmName("setID")
@PrimaryKey val id: ID,

在您的 ID 参数声明之前禁用重整。 对我有帮助