我的 API 响应有以下模型:
@Entity(tableName = TABLE_NAME)
class WeatherEntry {
@PrimaryKey(autoGenerate = true)
var wID: Long? = null
@SerializedName("dt")
@ColumnInfo(name = COLUMN_DATE)
var date: String = ""
@SerializedName("city")
@Embedded(prefix = "location_")
var location: Location? = null
@SerializedName("main")
@Embedded(prefix = "main_")
var main: Main? = null
@SerializedName("weather")
@TypeConverters(Converters::class)
@Embedded(prefix = "weather_")
var weather: ArrayList<Weather>? = null
@SerializedName("wind")
@Embedded(prefix = "wind_")
var wind: Wind? = null
}
天气 repo
从本地或远程数据源获取数据,我将 forceRemote
设置为 true
,否则一开始就不会显示数据。
class WeatherRepository @Inject constructor(@Local var localDataSource: WeatherDataSource, @Remote var remoteDataSource: WeatherDataSource) :
WeatherDataSource {
private var caches: MutableList<WeatherEntry> = mutableListOf()
override fun getWeatherEntries(location: String, forceRemote: Boolean): Flowable<MutableList<WeatherEntry>> {
if (forceRemote) {
return refreshData(location)
} else {
return if (caches.isNotEmpty()) {
// if cache is available, return it immediately
Flowable.just(caches)
} else {
// else return data from local storage
localDataSource.getWeatherEntries(location, false)
.take(1)
.flatMap(({ Flowable.fromIterable(it) }))
.doOnNext { question -> caches.add(question) }
.toList()
.toFlowable()
.filter({ list -> !list.isEmpty() })
.switchIfEmpty(refreshData(location)) // If local data is empty, fetch from remote source instead.
}
}
}
/**
* Fetches data from remote source.
* Save it into both local database and cache.
*
* @return the Flowable of newly fetched data.
*/
private fun refreshData(location: String): Flowable<MutableList<WeatherEntry>> {
return remoteDataSource.getWeatherEntries(location,true).doOnNext({
// Clear cache
caches.clear()
// Clear data in local storage
localDataSource.deleteAllWeatherEntries()
}).flatMap(({ Flowable.fromIterable(it) })).doOnNext({ entry ->
caches.add(entry)
localDataSource.insertWeatherEntry(entry)
}).toList().toFlowable()
}
本地数据源
class WeatherLocalDataSource @Inject constructor(private var weatherDao: WeatherDao): WeatherDataSource {
override fun insertWeatherEntry(weatherEntry: WeatherEntry) {
return weatherDao.insert(weatherEntry)
}
...
}
远程数据源 这绝对有效,因为我正在从 API 获取所有信息。
class WeatherRemoteDataSource @Inject constructor(var weatherService: WeatherService) :
WeatherDataSource {
override fun getWeatherEntries(location: String, forceRemote: Boolean): Flowable<MutableList<WeatherEntry>> {
return weatherService.getForecast(
location,
"json",
"metric",
BuildConfig.OPEN_WEATHER_MAP_API_KEY
).map(WeatherForecastResponse::weatherEntries)
}
}
DAO
@Dao
interface WeatherDao {
...
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(weatherEntry: WeatherEntry)
}
数据库
@Database(
entities = [(WeatherEntry::class)],
version = 1
)
abstract class WeatherDatabase : RoomDatabase() {
abstract fun weatherDao(): WeatherDao
}
所有其他字段都可以正常工作,但 wID
始终为空。我的实现有什么问题?
我已经尝试将其默认值更改为 0
并将类型更改为 Int 但这也不起作用。
最佳答案
尝试使 id 不可为空:
@PrimaryKey(autoGenerate = true)
var wID: Long = 0
编辑: 我在示例代码中找到了这个 here . 你可以让你的@Insert 方法返回插入行对象的 id,所以你可以这样做:
在你的道中:
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(weatherEntry: WeatherEntry) : Long
在您的刷新数据方法中:
private fun refreshData(location: String): Flowable<MutableList<WeatherEntry>> {
return remoteDataSource.getWeatherEntries(location,true).doOnNext({
// Clear cache
caches.clear()
// Clear data in local storage
localDataSource.deleteAllWeatherEntries()
}).flatMap(({ Flowable.fromIterable(it) })).doOnNext({ entry ->
val entryID = localDataSource.insertWeatherEntry(entry)
entry.wID = entryID
caches.add(entry)
}).toList().toFlowable()
}
关于java - 房间不会自动生成主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49476044/