3

Not sure what is causing this, but i am trying request data from the api which includes an array of Message objects. If i print the result to the console, the data is correct apart from Messages=null when i would expect Message to be an array of objects. I can't understand what i've missed?

I'm getting this error: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter messages

Could anyone point me in the right direction? Code below for the class:

const val PROFILE_RESPONSE_ID = 0

@Entity(tableName = "profile")
data class ProfileResponse(
    val id: Int,
    val name: String,
    val code: String,
    val title: String,
    @SerializedName("profile_image")
    val profileImage: String,
    @SerializedName("background_image")
    val backgroundImage: String,
    @Embedded(prefix = "messages_")
    val messages: ArrayList<Messages>,
) {
    @PrimaryKey(autoGenerate = false)
    var responseId: Int = PROFILE_RESPONSE_ID
}

Sample JSON:

{
  "id": 44,
  "name": "Jason",
  "code": "jason",
  "title": "Jason Scott",
  "profile_image": "https://sampleurl.com/sample_profile.jpg",
  "background_image": "",
  "messages": [
    {
      "id": 0001,
      "message": "Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.",
      "timestamp": "Thu, 01 Jan 1970 01:00:00 +0100",
    }
    {
      "id": 0002,
      "message": "Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.",
      "timestamp": "Thu, 01 Jan 1970 01:00:00 +0100",
    }
    {
      "id": 0003,
      "message": "Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.",
      "timestamp": "Thu, 01 Jan 1970 01:00:00 +0100",
    }
}
9
  • 1
    Like you mentioned messages is null but the kotlin compiler thinks messages not null and you're trying to set it null. Commented Jan 8, 2019 at 17:28
  • But it shouldn't be null nor am i trying to set it to be null (not intentionally anyway), it should have the array of message objects pulled down from the api? Commented Jan 8, 2019 at 17:29
  • Check if the server is sending you the messages_ json object and it is properly getting converted to array list of messages. Commented Jan 8, 2019 at 17:34
  • Not sure if this makes much difference but originally was List<Messages> but was getting e: 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 so converted it to a List. Does it need to be a List or should ArrayList work just fine? (or an array of objects) Commented Jan 8, 2019 at 17:39
  • 1
    @Jason Embedded works for a single object to embed its fields in the entity table. In the case of a List of objects, you have a one to many relation and this is modeled in Room with a Relation annotation in a new pojo(along with some changes to your current code). developer.android.com/training/data-storage/room/… Commented Jan 9, 2019 at 10:48

1 Answer 1

3

Managed to solve this by removing @Embedded as I didn't necessarily need the data in another table, and added a TypeConverter to convert the list into a String and back (This question helped). For reference for anyone else:

TypeConvertor Class

class Convertors {

    @TypeConverter
    fun listToJson(value: List<Message>?): String {
        return Gson().toJson(value)
    }

    @TypeConverter
    fun jsonToList(value: String): List<Message>? {
        val objects = Gson().fromJson(value, Array<Message>::class.java) as Array<Message>
        val list = objects.toList()
        return list
    }

}

Then adding the @TypeConverters to my database class.

Database Class

@Database(entities = [ProfileResponse::class], version = 1)
@TypeConverters(Convertors::class)
abstract class MainDatabase: RoomDatabase() {

    abstract fun profileResponseDao(): ProfileResponseDao

}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.