Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Room Persistence: Error:Entities and Pojos must have a usable public constructor

I'm converting a project to Kotlin and I'm trying to make my model (which is also my entity) a data class I intend to use Moshi to convert the JSON responses from the 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
)

I can't build the app cause of the following error

Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type). Cannot find setter for field.

The examples I found are not far from this

Ideas on how to solve it?

like image 370
Leonardo Deleon Avatar asked Jun 11 '17 15:06

Leonardo Deleon


4 Answers

It's not a problem in your case, but for others, this error can occur if you have @Ignore params in your primary constructor, i.e. Room expects to have either:

  • parameterless constructor or
  • constructor with all fields not marked with @Ignore

for example:

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

will not work. This will:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String) 
like image 153
daneejela Avatar answered Oct 23 '22 08:10

daneejela


Had a similar issue before.

First I've updated/added apply plugin: 'kotlin-kapt' to gradle.

Next, I've used it instead of annotationProcessor in gradle:

kapt "android.arch.persistence.room:compiler:1.0.0-alpha4"

Tha last thing was to create an immutable data class:

@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
)

UPDATE:

This solution works when you have classes for the model and classes for Database in the same Android Module. If you have model classes in Android Library module and the rest of the code in your main module, Room will NOT recognize them.

like image 30
Tomek Polański Avatar answered Oct 23 '22 08:10

Tomek Polański


I had the same issue. You can move the @Ignore fields to class body. For example :

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String
){
    //here
    @Ignore var overview: String
 }
like image 30
Thilaw Fabrice Avatar answered Oct 23 '22 09:10

Thilaw Fabrice


you need to specify a secondary constructor like so:

@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)
}    
like image 29
evanchooly Avatar answered Oct 23 '22 08:10

evanchooly