I have 3 entitites (Location, Current and Forecast) with following relationships:
1.) Location - Current (one-one)
2.) Location - Forecast (one-one)
Now to retrieve data from it i wrote a query
@Transaction
@Query(
"SELECT weather_location.id, name, current_weather.*, weather_forecast.* FROM weather_location " +
"INNER JOIN current_weather ON current_weather.locationId = weather_location.id " +
"INNER JOIN weather_forecast ON weather_forecast.locationId = weather_location.id "
)
fun getWeather(): Flow<List<WeatherModel>>
WeatherModel:
data class WeatherModel(
val id: String,
val name: String,
@Relation(
parentColumn = "id", <- line 12
entityColumn = "locationId"
)
val currentWeather: CurrentWeatherEntity,
@Relation(
parentColumn = "id",
entityColumn = "locationId"
)
val weatherForecast: WeatherForecastEntity
)
Error:
java.lang.NullPointerException: Parameter specified as non-null is null: method com.anshtya.weatherapp.data.local.model.WeatherModel.<init>, parameter currentWeather
at com.anshtya.weatherapp.data.local.model.WeatherModel.<init>(Unknown Source:12)
at com.anshtya.weatherapp.data.local.dao.WeatherDao_Impl$16.call(WeatherDao_Impl.java:609)
at com.anshtya.weatherapp.data.local.dao.WeatherDao_Impl$16.call(WeatherDao_Impl.java:568)
Why i am getting this error? Note: Query works in App Inspection of Android Studio
Really you have a 1-many, which may be 0 and hence potentially null. You could eliminate the error by allowing nulls using
val currentWeather: CurrentWeatherEntity?,andval weatherForecast: WeatherForecastEntity?However, you will then find that you get nulls, and hence why you are getting the NPE, rather than the expected related data (see example below)
When you use
@Relationannotation you are effectively saying use a subquery to build the related object (and the warning if you do not use@Transaction). That is the JOIN's are effectively ignored other than if they effect the non@Relationfields, i.e. the parents (WeatherLocationEntity's) that are extracted.Typically when using an
@Relationyou would expect a List, which may be empty (as opposed to null).So if you use:-
Along with for example (instead of your
getWeather()) :-Then the result will be as expected (unlike as when using the
getWeather). Consider the following in the database:-Then the output obtained using:-
will be:-
Of course for a 1-1, you might as well include all the data in a single table.