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

前端 未结 24 1753
长发绾君心
长发绾君心 2020-12-01 09:05

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<

相关标签:
24条回答
  • 2020-12-01 09:16

    Like it's said in the Room docs, you are required to make an empty public constructor. At the same time, if you want to declare other custom constructors, you must add @Ignore annotation.

    @Entity
    public class CartItem {
        @PrimaryKey
        public int product_id;
        public int qty;
    
        public CartItem() {
        }
    
        @Ignore
        public CartItem(int product_id, int count) {
            this.product_id = product_id;
            this.qty = count;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 09:17

    For me all I had to do was to add a constructor to the data class with empty params sent to it like so:

        @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("","","","","","","")
    }
    
    0 讨论(0)
  • 2020-12-01 09:18

    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) 
    
    0 讨论(0)
  • 2020-12-01 09:19

    Kotlin allows long as a parameter name, but this won't work when room generates java code.

    0 讨论(0)
  • 2020-12-01 09:20

    As stated in Room Database Entity:

    Each entity must either have a no-arg constructor or a constructor whose parameters match fields (based on type and name).

    So adding an empty constructor and annotating your parameterized constructor with @Ignore will solve your problem. An example:

    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 讨论(0)
  • 2020-12-01 09:24

    What worked for me:

    @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
    )
    
    0 讨论(0)
提交回复
热议问题