java - 房间不会自动生成主键

标签 java android kotlin android-room

我的 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/

相关文章:

java - ThreadLocal<T>::getMap 如何工作?

java - 无法通过 IntelliJ 打开调试器端口

java - 使用 Spring LDAP 在 Java 中进行身份验证

android - 检查 ExpandableListView 中的 Firstvisible item 是 Groupindicator?

android - 如何在 android fragment 中使用 SQLite?

Java关键字在eclipse中不改变颜色

android - 如何尽早在 build.gradle 中获取构建类型

android - 应用程序小部件不会显示在应用程序抽屉中,似乎与无效尺寸有关

android - TextInputEditText 提示被框轮廓覆盖

Kotlin:多种类型的智能转换