I need when refresh page make request to API
and insert getting data to my room database. But when I try to insert data I get io.reactivex.exceptions.OnErrorNotImplementedException: UNIQUE constraint failed: data.id (code 1555).
So I decided to check is my table empty and if isn't make update request, but so my recyclerview doesn't work normally, and data doesn't update properly on db. Here is my code:
private void getData() {
progressBar.setVisibility(View.VISIBLE);
APIInterface service = RetrofitInstance.getRetrofitInstance().create(APIInterface.class);
Call<DataAll> call = service.getData();
call.enqueue(new Callback<DataAll>() {
@Override
public void onResponse(Call<DataAll> call, Response<DataAll> response) {
if(response.body() != null) {
List<Data> allData = response.body().getData();
Disposable disposable = db.dataDao().dataSize().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer dbSize) throws Exception {
if(dbSize > 0)
updateData(allData);
else
insertData(allData);
fillListFromDb();
}
});
}
}
@Override
public void onFailure(Call<DataAll> call, Throwable t) {
tvErrorMessage.setVisibility(View.VISIBLE);
recyclerDataList.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
swipeRefreshToUpdateList.setRefreshing(false);
Toast.makeText(getApplicationContext(), R.string.errorMessage, Toast.LENGTH_LONG).show();
t.printStackTrace();
}
});
}
private void fillListFromDb() {
Disposable disposable = db.dataDao().getAllData().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<List<Data>>() {
@Override
public void accept(List<Data> data) throws Exception {
listData.clear();
listData.addAll(data);
adapter = new MyAdapter(listData);
adapter.notifyDataSetChanged();
recyclerDataList.setAdapter(adapter);
progressBar.setVisibility(View.GONE);
swipeRefreshToUpdateList.setRefreshing(false);
}
});
}
private void updateData(List<Data> data) {
Completable.fromAction( () ->
db.dataDao().updateData(data))
.subscribeOn(Schedulers.io())
.subscribe();
}
private void insertData(List<Data> data) {
Completable.fromAction(() ->
db.dataDao().addData(data)).
subscribeOn(Schedulers.io())
.subscribe();
}
And onCreate method:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ……
swipeRefreshToUpdateList.setOnRefreshListener(() -> {
tvErrorMessage.setVisibility(View.GONE);
recyclerDataList.setVisibility(View.VISIBLE);
getData();
});
}
Please help me
If you want an insert
operation to overwrite existing object in DB, then you should use OnConflictStrategy.REPLACE
.
See example:
@Dao
interface CatDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCats(cats: List<Cat>)