改造响应对象中的嵌入式房间实体字段未在运行时初始化

时间:2020-04-16 16:48:22

标签: json android-studio kotlin retrofit2 android-room

我有一个CurrentWeatherResponse对象,其中包含使用Retrofit从天气API中恢复的JSON数据。这是JSON响应格式:

{
"latitude": 37.8267,
"longitude": -122.4233,
"timezone": "America/Los_Angeles",
"currently": {
  "time": 1587054875,
  "summary": "Mostly Cloudy",
  "icon": "partly-cloudy-day",
  "nearestStormDistance": 107,
  "nearestStormBearing": 119,
  "precipIntensity": 0,
  "precipProbability": 0,
  "temperature": 11.49,
  "apparentTemperature": 11.49,
  "dewPoint": 10.14,
  "humidity": 0.91,
  "pressure": 1012.9,
  "windSpeed": 2.73,
  "windGust": 3.84,
  "windBearing": 171,
  "cloudCover": 0.64,
  "uvIndex": 2,
  "visibility": 16.093,
  "ozone": 360.9
  },
"offset": -7
}

CurrentWeatherResponse内部,我分别有两个字段currentWeatherEntry: CurrentWeatherEntryval location: WeatherLocation。这些字段中的每个字段都是一个房间@Entity类。现在我注意到,尽管"currently" json数据已成功传递到CurrentWeatherEntry字段中,但@Embedded位置WeatherLocation字段从未初始化。当我运行应用程序或使用数据库检查器时,我可以看到WeatherLocation实体甚至没有初始化其ID字段。我在这里想念什么?

CurrentWeatherResponse类:

data class CurrentWeatherResponse(
    // Tells GSON that the "currently" field of the JSON returned by the
    // API should be tied with our CurrentWeatherEntry data class
    @SerializedName("currently")
    val currentWeatherEntry: CurrentWeatherEntry,
    @Embedded
    val location: WeatherLocation
) {
    init {
        location.setEpochTimeVal(currentWeatherEntry.time)
    }
}

CurrentWeatherEntry实体:

const val CURRENT_WEATHER_ID = 0

@Entity(tableName = "current_weather")
data class CurrentWeatherEntry(
    val time: Long, // epoch timestamp
    val icon: String,
    val summary: String,
    val precipProbability: Double,
    val temperature: Double
) {
    @PrimaryKey(autoGenerate = false)
    var id:Int = CURRENT_WEATHER_ID
}

WeatherLocaiton实体:

const val WEATHER_LOCATION_ID = 0

@Entity(tableName = "weather_location")
data class WeatherLocation(
    val latitude: Double,
    val longitude: Double,
    val timezone: String
) {
    @PrimaryKey(autoGenerate = false)
    var id:Int = WEATHER_LOCATION_ID

    private var epochTimeVal:Long = 0

    val zonedDateTime:ZonedDateTime
        get() {
            val instant = Instant.ofEpochMilli(this.epochTimeVal)
            val zoneId = ZoneId.of(timezone)
            return ZonedDateTime.ofInstant(instant,zoneId)
        }

    fun setEpochTimeVal(time:Long) {
        this.epochTimeVal = time}
    fun getEpochTimeVal() : Long = epochTimeVal
}

2 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,则必须说@Embedded注释是Room的注释,而不是Gson的注释。因此,通过Retrofit将规则转换为您对Kotlin数据对象的响应不会起作用。

@Embedded注释仅对于Room Dao类可见,以将关系数据库转换为您方便的对象模型。

因此,您需要为Gson编写自己的TypeConvertor

答案 1 :(得分:0)

就像@MahdiRajabi所述,CREATE PROCEDURE employee_project ( emp_id in EMPLOYEES.EMPLOYEE_ID%TYPE, cur out SYS_REFCURSOR ) IS BEGIN OPEN cur FOR SELECT p.project_id, p.project_name FROM employees e INNER JOIN departments d ON ( e.department_id= d.department_id ) INNER JOIN projects p ON ( p.department_id = d.department_id) WHERE e.employee_id = emp_id; END; / 批注由Room使用,而不是Gson使用。这意味着从JSON响应返回到@Embedded类的latitudelongitudetimezone字段将被忽略,而CurrentWeatherResponse字段为只需分配location:WeatherLocation。通过在null中显式定义latitudelongitudetimezone字段,然后在{{1} }字段是使用getter访问的。现在一切都按预期工作!

CurrentWeatherResponse