Room Persistence: Error:Entities and Pojos Must Have a Usable Public Constructor

How to resolve Entities and POJOs must have a usable public constructor

You cannot have a List/Array etc as a column type. So your issue is centred on @Embedded val states: List<Int>

You could have a POJO e.g. StatesHolder :-

data class StatesHolder(
val stateList: List<Int>
)

and then have

@Entity(tableName = "training_session")
data class SessionEntity(
@PrimaryKey(autoGenerate = false) val id: Long,
@ColumnInfo(name = "current_state_marker") val currentState: Short,
val states: StatesHolder
)
  • Note that you cannot Embed StatesHolder as then that just inserts List. If you want to Embed then you have to Embed a wrapper that uses a StatesHolder.

You will then need TypeConverters to convert to and from a StatesHolder object to a type that can be stored. Probably a String and Probably a JSON respresentation of the StatesHold object e.g.

class Converters {

@TypeConverter
fun fromStatesHolder(sh: StatesHolder): String {
return Gson().toJson(sh)
}
@TypeConverter
fun toStatesHolder(sh: String): StatesHolder {
return Gson().fromJson(sh,StatesHolder::class.java)
}
}

You additionally need to use @TypeConverters annotation that defines the Converts::class. If coded at the @Database level the converters have full scope.

So after @Database(.....) you could have :-

@TypeConverters(Converters::class)

How to fix Entities and POJOs must have a usable public constructor

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

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

Please change names of the parameters such that it matches entity attributes.

  public User(int userId, String userName, String userGender, int userAge, int userWeight, int userHeight, String workoutPlan) {
this.userId = userId;
this.userName = userName;
this.userGender = userGender;
this.userAge = userAge;
this.userWeight = userWeight;
this.userHeight = userHeight;
this.workoutPlan = workoutPlan;
} ...

For persistance, it uses JavaBeans conventions in Room. For more information:
https://developer.android.com/training/data-storage/room/defining-data#java

Room Persistence: Entities and POJOs must have a usable constructor

For my first question, as suggested by CommonsWare and rmlan, was to change the parameter names in my constructor to match those of the variables.

The problem with the getters was that Room uses the JavaBeans Conventions for their names, so for example my getuUsername() should have rather been getUUsername(). After I changed all of the getters to match that the build was successful.

Source: Android Developers

Room Android Entities and POJOs must have a usable public constructor

@Embedded
@SerializedName("mediafiles")
var mediafiles: List<Mediafile>

AFAIK, you cannot use @Embedded for arbitrary things, which includes lists.

Either change this to use relations or use @TypeConverter and @TypeConverters to convert your List<Mediafile> into some valid column type, such as a String.

error: Entities and Pojos must have a usable public constructor - Java

I have solved the problem. Well, it seems like I can't use @Embedded with @TypeConverter mostly because the converter returns a String and it's primitive not a POJO class. Anyway, I removed the @Embedded annotation and it worked fine.



Related Topics



Leave a reply



Submit