Je convertis un projet en Kotlin et j'essaie de transformer mon modèle (qui est aussi mon entité) en classe de données J'ai l'intention d'utiliser Moshi pour convertir les réponses JSON de l'API
@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
)
Je ne peux pas créer l'application à cause de l'erreur suivante
Les entités et les pojos doivent avoir un constructeur public utilisable. Vous pouvez avoir un constructeur vide ou un constructeur dont les paramètres correspondent aux champs (par nom et type) . Impossible de trouver un setter pour le champ.
Les exemples que j'ai trouvés ne sont pas loin de this
Des idées sur la façon de le résoudre?
Avait un problème similaire avant.
D'abord, j'ai mis à jour/ajouté apply plugin: 'kotlin-kapt'
à gradle.
Ensuite, je l'ai utilisé à la place de annotationProcessor
in gradle:
kapt "Android.Arch.persistence.room:compiler:1.0.0-alpha4"
La dernière chose à faire était de créer une classe de données immuable:
@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
)
METTRE À JOUR:
Cette solution fonctionne lorsque vous avez des classes pour le modèle et des classes pour la base de données dans le même module Android. Si vous avez des classes de modèle dans le module Bibliothèque Android et le reste du code dans votre module principal, Room ne les reconnaîtra pas.
vous devez spécifier un constructeur secondaire comme ceci:
@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)
}
Ce qui a fonctionné pour moi:
@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
)
Je pense qu'une bonne option pour le résoudre est:
@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
)
Kotlin autorise longtemps le nom d'un paramètre, mais cela ne fonctionnera pas si room génère du code Java.
Pour moi, tout ce que j'avais à faire était d'ajouter un constructeur à la classe de données avec des paramètres vides envoyés comme suit
@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("","","","","","","")
}
J'ai également eu ce problème, mais je me suis rendu compte que le problème était que j'avais ajouté l'annotation @Embedded à une propriété qui disposait déjà d'un convertisseur de type. Par conséquent, toute personne ayant le même problème devrait vérifier soigneusement les déclarations de propriété de votre classe de modèle et s'assurer que le @ L'annotation incorporée ne se trouve pas sur une propriété à laquelle est associé un convertisseur de type.
Il s’est avéré qu’il s’agissait d’un bogue dans la bibliothèque https://github.com/googlesamples/Android-architecture-components/issues/49
https://issuetracker.google.com/issues/62851733
j'ai trouvé que c'est le bogue projection de @ Relation! pas un problème de langage Kotlin . basé sur Google GithubBrowserSample Java également une erreur, mais un message d'erreur différent.
ci-dessous est mon code kotlin:
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()
)
droite:
data class UserWithCommunities(
@Embedded
var user: User = User(0, null),
@Relation(parentColumn = "id",
entityColumn = "users_id",
entity = CommunityUsers::class)
var communityList: List<CommunityUsers> = emptyList()
)
J'ai eu ce problème avec une entité (tous les champs étaient correctement initialisés var
sans beaucoup de réponses suggèrent ici) qui incluait une liste d'éléments connexes non primitifs tels que l'OP dans cette question SO) eu. Par exemple:
@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()))
C’est-à-dire qu’il comporte un champ intégré et qu’il m’a fallu un certain temps pour comprendre que j’avais besoin d’un convertisseur de type pour la liste des entités du fournisseur (le compilateur ne lançait pas le Error:(58, 31) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
habituel. La solution était donc très similaire à cette réponse
Ce thread github de Google architecture composants a plus d'informations sur cette erreur trompeuse, mais ne sait pas si le problème a été résolu pour le moment.
Ajoutez simplement l'annotation ci-dessous à tout constructeur qui cause les erreurs et ajoutez un nouveau constructeur vierge.
@Ignorer
N'utilisez pas de classe de données, utilisez plutôt la classe normale. Cette méthode va résoudre le problème
Comme indiqué dans Base de données de salles Entity
:
Chaque entité doit avoir un constructeur sans argument ou un constructeur dont les paramètres correspondent aux champs (en fonction du type et du nom).
Donc, ajouter un constructeur vide et annoter votre constructeur paramétré avec @Ignore
résoudra votre problème. Un exemple:
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
// ...
}
Même bogue, solution beaucoup plus étrange: Ne retournez pas le curseur en utilisant reactivex Maybe<Cursor>
sur votre Dao. Flowable
, Single
et Observable
ne fonctionnaient pas non plus.
Il suffit de mordre la balle et de faire l'appel réactif en dehors de la requête Dao . Avant:
@Dao
interface MyDao{
@Query("SELECT * FROM mydao")
fun getCursorAll(): Flowable<Cursor>
}
Après:
@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