数据未正常更新(会议室数据库)

时间:2019-02-15 10:56:47

标签: android rx-java2 android-room android-database android-jetpack

我需要在刷新页面时向API发出请求,并将获取的数据插入到我的会议室数据库中。但是,当我尝试插入数据时,我得到了io.reactivex.exceptions.OnErrorNotImplementedException: UNIQUE constraint failed: data.id (code 1555).,因此我决定检查我的表是否为空,如果不是发出更新请求,则我的recyclerview无法正常工作,并且数据无法正确更新D b。这是我的代码:

 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();
    }

onCreate 方法:

   @Override
        protected void onCreate(Bundle savedInstanceState) {
  //  ……
      swipeRefreshToUpdateList.setOnRefreshListener(() -> {
                    tvErrorMessage.setVisibility(View.GONE);
                    recyclerDataList.setVisibility(View.VISIBLE);
                    getData();
                });
    }

请帮助我

2 个答案:

答案 0 :(得分:1)

如果您希望insert操作覆盖数据库中的现有对象,则应使用OnConflictStrategy.REPLACE

查看示例:

@Dao
interface CatDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertCats(cats: List<Cat>)

答案 1 :(得分:-1)

您必须在List<Data>中一一检查您updateData 例如:

@Override
        public void onResponse(Call<DataAll> call, Response<DataAll> response) {
            if(response.body() != null) {
                 List<Data> allData = response.body().getData();
                 for (Data data:allData){
                  if(isStored(data.getId())){
                      updateData(data);
                        else {
                        insertData(data);
                        }

                       }
                   }
                }  
            }
        }

您可以在DataDao findDataById(string id)中创建一个新方法,并使用boolean isStored(String id)方法并直接对其进行更新

祝你好运!希望对您有帮助。