Я воспользовался GithubBrowserSample от Google, чтобы начать работу с компонентами архитектуры Android и модернизацией.Все работает нормально, но у меня проблемы с собственной моделью данных из-за внешних ключей.
Допустим, у меня есть место:
@Entity(tableName = "place",
foreignKeys = [
ForeignKey(entity = User::class, parentColumns = ["user_id"], childColumns = ["place_created_by_user_id"])
],
indices = [
Index(value = ["place_created_by_user_id"], name = "place_created_by_user_index")
])
data class Place(
@SerializedName("id")
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "place_id")
var id: Long,
@SerializedName("name")
@ColumnInfo(name = "place_name")
var name: String?,
@SerializedName("created_by_user_id")
@ColumnInfo(name = "place_created_by_user_id")
var createdByUserId: Long?,
)
И пользователь:
@Entity(tableName = "user")
data class User(
@SerializedName("id")
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "user_id")
var id: Long,
@SerializedName("first_name")
@ColumnInfo(name = "user_first_name")
var firstName: String,
@SerializedName("last_name")
@ColumnInfo(name = "user_last_name")
var lastName: String,
)
По примеру Google метод извлечения мест в репозитории:
fun loadPlaces(): LiveData<Resource<List<Place>>> {
return object : NetworkBoundResource<List<Place>, List<Place>>(appExecutors) {
override fun saveCallResult(item: List<Place>) {
placeDao.insert(item)
}
override fun shouldFetch(data: List<Place>?): Boolean = true
override fun loadFromDb() = placeDao.getAll()
override fun createCall() = service.getPlaces()
override fun onFetchFailed() {
//repoListRateLimit.reset(owner)
}
}.asLiveData()
}
Так что обычно это просто работает (я пытался с сущностью без внешнего ключа), но это не удалось из-завнешнее ограничение:
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787)
Действительно, пользователь еще не загружен.Поэтому перед placeDao.insert(item)
я должен загрузить каждого пользователя, чтобы убедиться, что место найдет его.И это то же самое для каждой сущности и каждого внешнего ключа.Любые идеи о том, как я могу добиться этого, следуя этой архитектуре?
Дело в том, когда я вызываю loadPlaces()
в моей ViewModel, как это:
class PlacesViewModel(application: Application) : BaseViewModel(application) {
val places: LiveData<Resource<List<Place>>> = repository.loadPlaces()
}
Хранилище будет по своей природе загружать подключенных пользователейв места ...
Спасибо за вашу помощь.