it-swarm.com.de

Raumpersistenz: Fehler: Entitäten und Pojos müssen einen verwendbaren öffentlichen Konstruktor haben

Ich konvertiere ein Projekt in Kotlin und versuche, mein Modell (das auch meine Entität ist) zu einer Datenklasse zu machen Ich möchte Moshi verwenden, um die JSON-Antworten aus der API zu konvertieren

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String,
    var overview: String,
    var poster_path: String,
    var backdrop_path: String,
    var release_date: String,
    var vote_average: Double,
    var isFavorite: Int
)

Ich kann die App aufgrund des folgenden Fehlers nicht erstellen

Entitäten und Pojos müssen über einen verwendbaren öffentlichen Konstruktor verfügen. Sie können einen leeren Konstruktor oder einen Konstruktor haben, dessen Parameter mit den Feldern übereinstimmen (nach Name und Typ) . Setter für Feld kann nicht gefunden werden.

Die Beispiele, die ich gefunden habe, sind nicht weit entfernt von this

Ideen, wie man es löst?

37
Leonardo Deleon

Hatte vorher ein ähnliches Problem.

Zuerst habe ich apply plugin: 'kotlin-kapt' für Gradle aktualisiert/hinzugefügt.

Als Nächstes habe ich es in Gradle anstelle von annotationProcessor verwendet:

kapt "Android.Arch.persistence.room:compiler:1.0.0-alpha4"

Das letzte war, eine unveränderliche Datenklasse zu erstellen:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    val id : Int,
    val title: String,
    val overview: String,
    val poster_path: String,
    val backdrop_path: String,
    val release_date: String,
    val vote_average: Double,
    val isFavorite: Int
)

AKTUALISIEREN:

Diese Lösung funktioniert, wenn Sie Klassen für das Modell und Klassen für Datenbank im selben Android-Modul haben. Wenn Sie Modellklassen im Android Library-Modul und den Rest des Codes in Ihrem Hauptmodul haben, werden sie von Room NICHT erkannt.

40
Tomek Polański

sie müssen einen sekundären Konstruktor wie folgt angeben: 

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String,
    var overview: String,
    var poster_path: String,
    var backdrop_path: String,
    var release_date: String,
    var vote_average: Double,
    var isFavorite: Int
) {
    constructor() : this(0, "", "", "", "", "", 0.0, 0)
}    
12
evanchooly

Was für mich funktioniert hat:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int? = 0,
    var title: String? = "",
    var overview: String? = "",
    var poster_path: String? = "",
    var backdrop_path: String? = "",
    var release_date: String? = "",
    var vote_average: Double? = 0.0,
    var isFavorite: Int? = 0
)
7
stevenwood

Ich denke, dass eine gute Option für die Lösung es ist:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int = 0,
    var title: String = "",
    var overview: String = "",
    var poster_path: String = "",
    var backdrop_path: String = "",
    var release_date: String = "",
    var vote_average: Double = 0.0,
    var isFavorite: Int = 0
)
4
tito

In Ihrem Fall ist dies kein Problem, aber bei anderen kann dieser Fehler auftreten, wenn Sie @Ignore-Parameter in Ihrem Konstruktor haben, d. H.

  • parameterloser Konstruktor oder
  • konstruktor mit allen Feldern, die nicht mit @Ignore markiert sind

zum Beispiel:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String,
    @Ignore var overview: String) 

wird nicht funktionieren. Dieser Wille:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String) 
3
daneejela

Kotlin erlaubt als Parameternamen long, was jedoch nicht funktioniert, wenn der Raum Java-Code generiert.

2
Erik B

Für mich musste ich nur einen Konstruktor zur Datenklasse hinzufügen, wobei leere Parameter wie folgt gesendet wurden:

    @Entity(tableName = "posts")
data class JobPost(
    @Ignore
    @SerializedName("companyLogo")
    var companyLogo: String,
    @Ignore
    @SerializedName("companyName")
    var companyName: String,
    @Ignore
    @SerializedName("isAggregated")
    var isAggregated: String,
    @PrimaryKey(autoGenerate = false)
    @SerializedName("jobID")
    var jobID: String,
    @Ignore
    @SerializedName("jobTitle")
    var jobTitle: String,
    @Ignore
    @SerializedName("postedOn")
    var postedOn: String,
    @Ignore
    @SerializedName("region")
    var region: String
) {
    constructor() : this("","","","","","","")
}
2
Ahmed Awad

Ich hatte auch dieses Problem, aber ich erkannte, dass das Problem darin bestand, dass ich die @Embedded-Annotation zu einer Eigenschaft hinzufügte, die bereits einen Typkonverter hatte. Daher sollte jeder, der das gleiche Problem hat, die Property-Deklarationen für Ihre Modellklasse sorgfältig prüfen und sicherstellen, dass das @ Die eingebettete Anmerkung befindet sich nicht in einer Eigenschaft, der ein Typkonverter zugeordnet ist.

2
caleb grimah

Es stellte sich als Fehler in der Bibliothek heraus https://github.com/googlesamples/Android-architecture-components/issues/49

1
Leonardo Deleon

https://issuetracker.google.com/issues/62851733

ich fand das ist @ Relation Projektion Bug! Kein Kotlin-Sprachproblem Google-basiertes GithubBrowserSample Java hat ebenfalls einen Fehler, jedoch eine andere Fehlermeldung.

unten ist mein Kotlin-Code:

data class UserWithCommunities(
        @Embedded
        var user: User = User(0, null),

        @Relation(parentColumn = "id",
                entityColumn = "users_id",
                entity = CommunityUsers::class,
                projection = arrayOf("communities_id")) // delete this line.
        var communityIds: List<Int> = emptyList()
)

recht:

data class UserWithCommunities(
        @Embedded
        var user: User = User(0, null),

        @Relation(parentColumn = "id",
                entityColumn = "users_id",
                entity = CommunityUsers::class)
        var communityList: List<CommunityUsers> = emptyList()
)
1
changhao cui

Ich hatte dieses Problem mit einer Entität (alle Felder wurden ordnungsgemäß initialisiert vars wie viele der hier vorgeschlagenen Antworten), die eine Liste verwandter, nicht-primitiver Elemente wie das OP in diese enthielt SO Frage hatte. Zum Beispiel:

@Entity(tableName = "fruits")
data class CachedFruitEntity(
        @PrimaryKey var id: Long = 0L,
        @Embedded(prefix = "buyer_") var buyerEntity: CachedBuyerEntity? = null
        @TypeConverters(VendorsConverter::class)
        var vendorEntities: List<CachedVendorEntity?> = listOf()))

Das heißt, es hat ein eingebettetes Feld, und es dauerte eine Weile, bis mir klar wurde, dass ich tatsächlich einen Typkonverter für die Entitätsliste des Anbieters benötigte (der Compiler hat also nicht die übliche Error:(58, 31) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. geworfen) Lösung war sehr ähnlich zu diese Antwort

Dieser google architecture components github thread enthält weitere Informationen zu diesem irreführenden Fehler, ist sich jedoch nicht sicher, ob das Problem bereits behoben wurde.

1
kip2

Für mich habe ich 'lat' & 'long' als Variablennamen in der Datenklasse (Entity) für Kotlin verwendet, so dass das Umbenennen in Latitude & Longitude funktioniert hat.

Funktioniert nicht:

@Entity(tableName = "table_User")
data class User(@PrimaryKey var userId : Int, @ColumnInfo(name = "first_name") 
var firstName: String
            , @ColumnInfo(name = "last_name") var lastName: String
            , @ColumnInfo(name = "password") var password: String
            , @ColumnInfo(name = "dob") var dob: Long
            , @ColumnInfo(name = "address") var address: String
            , @ColumnInfo(name = "lat") var latitude: Double
            , @ColumnInfo(name = "long") var longitude: Double) {

}

Working:

@Entity(tableName = "table_User")
data class User(@PrimaryKey var userId : Int, @ColumnInfo(name = "first_name") 
var firstName: String
            , @ColumnInfo(name = "last_name") var lastName: String
            , @ColumnInfo(name = "password") var password: String
            , @ColumnInfo(name = "dob") var dob: Long
            , @ColumnInfo(name = "address") var address: String
            , @ColumnInfo(name = "latitude") var latitude: Double
            , @ColumnInfo(name = "longitude") var longitude: Double) {

}
0

Fügen Sie einfach die folgende Anmerkung zu einem Konstruktor hinzu, der die Fehler verursacht, und fügen Sie einen neuen leeren Konstruktor hinzu.

@Ignorieren

0
Harbdollar

Nicht zur Datenklasse verwenden, sondern normale Klasse. Diese Methode löst das Problem

0
Mustafa

Mit 2.1.0-alpha6 erwies es sich in Dao als ungültiger Rückgabetyp. Wenn der Rückgabetyp wie erwartet korrigiert wurde, wurde er korrigiert.

0
Vairavan

Wie in Raumdatenbank Entity angegeben:

Jede Entität muss entweder einen no-arg-Konstruktor oder einen Konstruktor haben deren Parameter mit Feldern übereinstimmen (basierend auf Typ und Name).

Durch das Hinzufügen eines leeren Konstruktors und das Kommentieren Ihres parametrisierten Konstruktors mit @Ignore wird Ihr Problem gelöst. Ein Beispiel:

public class POJO {

    long id;

    String firstName;

    @Ignore
    String lastName;

    public POJO() {
    }

    @Ignore
    public POJO(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    // getters and setters
    // ...

}
0
Rajarshi

Gleicher Fehler, viel merkwürdigere Lösung: Den Cursor nicht mit dem reaktiven x Maybe<Cursor> auf dem Dao zurückgeben. Flowable, Single und Observable funktionierten ebenfalls nicht.

Beißen Sie einfach die Kugel und machen Sie den reaktiven Anruf außerhalb der Dao-Anfrage.

@Dao
interface MyDao{
    @Query("SELECT * FROM mydao")
    fun getCursorAll(): Flowable<Cursor>
}

Nach dem:

@Dao
interface MyDao{
    @Query("SELECT * FROM mydao")
    fun getCursorAll(): Cursor
}

Meta:

Android Studio 3.2
Build #AI-181.5540.7.32.5014246, built on September 17, 2018
JRE: 1.8.0_152-release-1136-b06 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
macOS 10.12.6
0
Blaze Gawlik