2

I got this error when I tried to launch my app while using sqlite database.

I have 3 data classes in seperate files:

@Entity(tableName = "movies")
data class MovieNews(
    @PrimaryKey(autoGenerate = true)
    var id: Int? = null,
    @SerializedName("movie_db")
    @Embedded(prefix = "movies_")
    val movies: List<Movies>? = null,
)

data class Movies(
    val description: String? = null,
    @Embedded(prefix = "actors_")
    val actors: List<Actors>? = null,

)

data class Actors(
    val name: String? = null
    val age: Int? = null
)

When I launched the app I got the error:

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). - java.util.List

How can I fix this error?

Don't know if this is related to the problem, but I have this warning

w: [kapt] Incremental annotation processing requested, but support is disabled because the following processors are not incremental: androidx.room.RoomProcessor (DYNAMIC).

I also saw bunch of questions about this error, none of them solved my problem

UPDATE:

If I comment out the Embedded line, the app does compile.

I dug into stackoverflow questions and what I found that probably there is a problem with Embedded and Lists.

   @SerializedName("movie_db")
    @Embedded(prefix = "movies_")
    val movies: List<Movies>? = null,
Noam
  • 485
  • 1
  • 7
  • 18

1 Answers1

3

The general case:

data class MyDataClass(
  var myfield: String
){
  constructor(myfield: String): this(myfield)
}

For your data classes: Just provide a default value in the constructor:

@Entity(tableName = "movies")
data class MovieNews(
    @PrimaryKey(autoGenerate = true)
    var id: Int? = null,
    @SerializedName("movie_db")
    @Embedded(prefix = "movies_")
    val movies: List<Movies>? = null,
){
  constructor(): this(0, "", listOf())
}

data class Movies(
    val description: String? = null,
    @Embedded(prefix = "actors_")
    val actors: List<Actors>? = null,
) // same

data class Actors(
    val name: String? = null
    val age: Int? = null
) //same

Why does this happen? Because Room doesn't know how to tell the Java generated code how to initialize null fields (Java does not support default values)

If you don't like the solution: Just remove the ? and make everything a val BUT provide a default value.

The second thing is unrelated to your problem but can be fixed by adding:

javaCompileOptions {
            annotationProcessorOptions {
                arguments = [
                        "room.schemaLocation"  : "$projectDir/schemas".toString(),
                        "room.incremental"     : "true",
                        "room.expandProjection": "true"]
            }
        }

In your build.gradle

Boken
  • 4,825
  • 10
  • 32
  • 42
coroutineDispatcher
  • 7,718
  • 6
  • 30
  • 58
  • 1
    Thank you for your detailed answer, but unfortunately none of the answer works for me. See my update about the embedded line, maybe it can direct you the right direction – Noam Apr 28 '20 at 14:26
  • Does this article help? https://www.coroutinedispatcher.com/2019/08/solving-room-cannot-find-setter-for.html – coroutineDispatcher Apr 28 '20 at 16:27