So I have one database table on the backendless. I’m trying to fetch that data inside my Android app. However when I do that, I get this exception:
2022-03-26 09:40:09.719 9124-9161/com.example.backendlesstest E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: com.example.backendlesstest, PID: 9124
java.lang.IllegalArgumentException: Missing public, default no-argument constructor
at com.backendless.Persistence.of(Persistence.java:883)
at com.example.backendlesstest.presentation.screen.home.HomeScreenKt$HomeScreen$1$1.invokeSuspend(HomeScreen.kt:26)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
This is how my model class looks like. The name of the class is the same as the table name on backendless.
@Serializable
data class ColorPalette(
@SerialName("approved")
val approved: Boolean,
@SerialName("___class")
val classX: String?,
@SerialName("color1")
val color1: String?,
@SerialName("color2")
val color2: String?,
@SerialName("color3")
val color3: String?,
@SerialName("color4")
val color4: String?,
@SerialName("color5")
val color5: String?,
@SerialName("created")
val created: Long,
@SerialName("objectId")
val objectId: String,
@SerialName("ownerId")
val ownerId: String?,
@SerialName("updated")
val updated: Long
)
And this is the code/trigger:
LaunchedEffect(Unit) {
this.launch(Dispatchers.IO) {
Backendless.Data.of(ColorPalette::class.java)
.find(object : AsyncCallback<List<ColorPalette>> {
override fun handleResponse(response: List<ColorPalette>?) {
response?.forEach {
Log.d("Response", "Approved ${it.approved}")
Log.d("Response", "Color 1 ${it.color1}")
Log.d("Response", "Color 2 ${it.color2}")
Log.d("Response", "Color 3 ${it.color3}")
Log.d("Response", "Color 4 ${it.color4}")
Log.d("Response", "Color 5 ${it.color5}")
}
}
override fun handleFault(fault: BackendlessFault) {
Log.d("Response", "ERROR ${fault.code}")
Log.d("Response", "ERROR ${fault.message}")
}
})
}
}
Hi.
The error says to you: “Missing public, default no-argument constructor.”
Check, whether your entity (which you save/retrieve) has default no-argument constructor.
I’ve tried setting default values for each field inside a class in order to have an empty constructor, like this:
@Serializable
data class ColorPalette(
@SerialName("approved")
val approved: Boolean = false,
@SerialName("___class")
val classX: String? = "",
@SerialName("color1")
val color1: String? = "",
@SerialName("color2")
val color2: String? = "",
@SerialName("color3")
val color3: String? = "",
@SerialName("color4")
val color4: String? = "",
@SerialName("color5")
val color5: String? = "",
@SerialName("created")
val created: Long = 0L,
@SerialName("objectId")
val objectId: String = "",
@SerialName("ownerId")
val ownerId: String? = "",
@SerialName("updated")
val updated: Long = 0L
)
But I’m not able to retrieve the data successfully. Instead I get those default values. For each row inside my backendless table, I get those default values, instead of the real ones. Not sure why tho.
Hi @Stefan_Jovanovic ,
Does table name matches your class name?
Also pay attention to names of the fields - they should be the same as table columns names. @SerialName
annotation will be ignored by Java SDK.
Regards, Andriy
Oh okay, I have removed @SerialName annotation. Now I have also set the right names as you can see in this image down below, but still getting the same result (default values from the class):
data class ColorPalette(
val approved: Boolean = false,
val color1: String = "",
val color2: String = "",
val color3: String = "",
val color4: String = "",
val color5: String = "",
// val created: Long = 0L,
val objectId: String = "",
val ownerId: String = "",
// val updated: Long = 0L
)
Btw am I allowed to add only those fields that I need, or should I add all of them?
@Stefan_Jovanovic ,
Could you please try to use regular class instead of data class? Do not forget about getters and setters for your fields.
Btw am I allowed to add only those fields that I need, or should I add all of them?
You can add all fields which you need. Those which are not present in table will be ignored.
Regards, Andriy
I’ve removed the ‘data’ keyword, so I’m using a regular class now, and still it’s the same.
I’m not sure why this is happening. Do you have some project written in Kotlin that I can check out?
@Stefan_Jovanovic ,
This is really strange behavior. At first I though that data class caused it. Could you please try to use Map-driven data store instead for a test ( Backendless.Data.of("ColorPalette").find(...)
)?
Couple more questions. Do you receive in result the same amount of objects as you have records in table (or max page size)? These objects do not have even correct value for objectId field?
Do you have some project written in Kotlin that I can check out?
Unfortunately no, all our examples are written in Java.
Regards, Andriy
Yes I’m able to receive the exact data, when using Map driven data. However It would be handy to just map that data in a whole object instead, that’s why I’m trying this other method.
Yes I receive the same amount of result as the number of records in my database, however for the actual values I’m getting those default values I’ve setup in my model class ColorPalette.
Hi @Stefan_Jovanovic ,
Could you please change val
to var
in the fields definition of your entity class and try once more?
It looks like in Kotlin fields which were defined using val
do not have setters. That is why you received such behavior. Setters are required for entity classes (Data Object - Backendless SDK for Android/Java API Documentation)
I have tried to reproduce your problem in my app. With val
I got the same problem as yours but when I used var
instead for class fields the problem gone.
Regards, Andriy
1 Like