Raumdatenbank mit Kotlin-Inline-Klasse als Entitätsfeld

9

Ich versuche, Room ( https://developer.android.com/topic/libraries/architecture/room ) mit Kotlins Inline-Klassen zum Laufen zu bringen, wie in Jake Whartons Artikel Inline Classes Make Great Database IDs beschrieben :

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

inline class ID(val value: String)

Beim Kompilieren beschwert sich dieser Raum darüber

Entitäten und Pojos müssen einen verwendbaren öffentlichen Konstruktor haben. Sie können einen leeren Konstruktor oder einen Konstruktor haben, dessen Parameter mit den Feldern übereinstimmen (nach Name und Typ).

Wenn ich mir den generierten Java-Code anschaue, finde ich:

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);
}

Auf mysteriöse Weise ist der Standardkonstruktor jetzt privat.

Bei Verwendung Stringals Typ für id(oder a typealias) sieht der generierte Java-Klassenkonstruktor wie erwartet aus:

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

Kann jemand jetzt den Standardkonstruktor öffentlich halten, während Inline-Klassen als Datenentitätseigenschaften verwendet werden?

whlk
quelle
Haben Sie ein Problem dafür in einem Issue-Tracker angesprochen? Ich denke, dies muss mit Sicherheit geklärt werden
K.Os

Antworten:

0

Ich glaube, der Grund dafür ist, dass die ID-Klasse zur Laufzeit als String dargestellt wird. Der zusätzliche Parameter $ constructor_marker soll also die Eindeutigkeit der Konstruktorsignatur von MyEntity (String id, String title) gewährleisten, da dieser Konstruktor möglicherweise bereits definiert wurde. Aber ich spekuliere hier nur.

Könnten Sie versuchen, diesen Konstruktor in der MyEntity-Klasse explizit zu definieren und zu prüfen, ob er funktioniert?

Diego Marin
quelle
Dieser Konstruktor ist bereits explizit (aber mit syntaktischem Zucker) imdata class MyEntity(@PrimaryKey val id: ID, val title: String)
whlk
Sie haben einen Konstruktor mit (ID, String) -Parametern definiert, ich meinte einen Konstruktor mit (String, String). Ich habe es versucht, aber es scheint nicht möglich zu sein. Ich habe den Fehler "Platform Declaration Clash" erhalten.
Diego Marin