i am developing a weather forcast application that is having room as a local cache database for the json response that i am getting from the openweathermap api is as follow
{
"cod":"200",
"message":0,
"cnt":40,
"list":[
{
"dt":1590602400,
"main":{
"temp":306.2,
"feels_like":306.4,
"temp_min":306.07,
"temp_max":306.2,
"pressure":1006,
"sea_level":1004,
"grnd_level":950,
"humidity":41,
"temp_kf":0.13
},
"weather":[
{
"id":802,
"main":"Clouds",
"description":"scattered clouds",
"icon":"03n"
}
],
"clouds":{
"all":48
},
"wind":{
"speed":3.72,
"deg":183
},
"sys":{
"pod":"n"
},
"dt_txt":"2020-05-27 18:00:00"
},
{
"dt":1590613200,
"main":{
"temp":305.05,
"feels_like":303.65,
"temp_min":304.7,
"temp_max":305.05,
"pressure":1004,
"sea_level":1003,
"grnd_level":949,
"humidity":38,
"temp_kf":0.35
},
"weather":[
{
"id":803,
"main":"Clouds",
"description":"broken clouds",
"icon":"04n"
}
],
"clouds":{
"all":68
},
"wind":{
"speed":4.72,
"deg":197
},
"sys":{
"pod":"n"
},
"dt_txt":"2020-05-27 21:00:00"
},
{
"dt":1590624000,
"main":{
"temp":302.97,
"feels_like":304.29,
"temp_min":302.74,
"temp_max":302.97,
"pressure":1004,
"sea_level":1004,
"grnd_level":949,
"humidity":46,
"temp_kf":0.23
},
"weather":[
{
"id":802,
"main":"Clouds",
"description":"scattered clouds",
"icon":"03n"
}
],
"clouds":{
"all":47
},
"wind":{
"speed":1.48,
"deg":196
},
"sys":{
"pod":"n"
},
"dt_txt":"2020-05-28 00:00:00"
}
],
"city":{
"id":1269843,
"name":"Hyderabad",
"coord":{
"lat":17.3753,
"lon":78.4744
},
"country":"IN",
"population":3597816,
"timezone":19800,
"sunrise":1590538296,
"sunset":1590585318
}
}
on the basis of the json response i am having following data classes for the room schema
Record.class
@Entity(tableName = "Record")
data class Record(
@PrimaryKey(autoGenerate = true)
val rid:Long,
@SerializedName("dt_txt")
val dtTxt: String,
@Embedded(prefix = "main_")
val main: Main,
@Embedded(prefix = "rain_")
val rain: Rain,
@Embedded(prefix = "wind_")
val wind: Wind
)
Weather.class
@Entity(
tableName = "weather",
foreignKeys = [
ForeignKey(
entity = Record::class,
parentColumns = ["rid"],
childColumns = ["wid"],
onDelete = CASCADE
)
])
data class Weather(
@PrimaryKey(autoGenerate = true)
val wid:Long,
val description: String,
val icon: String,
val id: Int,
val main: String
)
WeatherRecord.class
class WeatherRecord (
@Embedded
val record: Record,
@Relation(parentColumn = "rid", entityColumn = "wid")
val weather:List<Weather>
)
and having other classes like Rain, Main, Wind, City, etc.
Now the Response class that i am having is
WeatherResponse.class
data class WeatherResponse(
val city: City,
val cnt: Int,
val cod: String,
val list: List<Record>,
val message: Int
)
as per the JSON response one can easily understand that Weather should be a field inside the Record class but it is not there, this is because of Weather is coming as a list, because of that i used foreign key and some small trickeries (as stated in the following answer(Android Room - Handling List of Objects in an Object and querying result)in my Dao Queries in order to store the list and fetch the weather list in the database
Dao Class
@Dao
interface WetherDataDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun upsert(data: Record)
@Insert
fun insert(weather:List<Weather>)
@Transaction
fun insert(weatherRecord: WeatherRecord){
upsert(weatherRecord.record)
insert(weatherRecord.weather)
}
@Query("Select * from Record")
fun getAllRecords():LiveData<WeatherRecord>
}
So before implemnenting the room i am getting the correct response(ie weather is coming as part of record) but after that i am not getting the weather as a part of Record and no where else.
i tried to resolve the problem by changing the list type from Record to WeatherRecord inside the WeatherRecord class but that also didn't resolved my problem (it is just printing the path of the class with some codes please refer to the screenshot ) so can anyone help me out to get i out of this problem you may suggest me any other possible solution that may change the whole database desing schema, i'll be my plesure to learn
As i am new to room so you can suggest me some interesting blogs on how i can desing the database schemas for this kind of complex databses
Thanks in advance
I don't know if my answer would be helpful. It is more about principles, not about practical instructions
Some reflections
There are several types of data classes' groups in application:
"Transfer" group. Structure of this group is formed by transfer interfaces. For example you have Android application, and there is back-end. You've got some JSON-protocol, you've decided to use Retrofit, so to get data in a proper form you have to build your classes according to JSON structure.
"Database" group. Structure of this group is not so strict, but if you use relational database (SQLite is one of them), there are some requirements you have to follow. For example you can't use another object as a field of table (just foreign key instead) and so on.
"Business logic" group. Structure of this group almost has no restrictions, it has to be efficient to use in the core of application's logic.
In simple Android applications all 3 data groups could be implemented with the same set of data classes, in complicated applications - they could be different with some kind of mapping with each other. Each company could specify some pattern how to build classes' hierarchy. So as always I think there is no silver bullet here.
In practice:
.