1

I have been using realm about more than a years, in many cases realm is good choice to construct Android database instead using SQLite. I have been using realm for one-one, one-many relationship and good for it. But, a moment a good. I discover realm NOT update my existing data in ONE-MANY relationship. This what i have done.

This code for populate skeleton data or a unit test

private void initData() {
    List<PackModel> packs = new ArrayList<>();
    for (int i = 0; i < 1; i++) {
        PackModel packModel = new PackModel();
        packModel.id = i;
        packModel.name = "Pack " + new Random().nextInt(100);

        List<FoodModel> foods = new ArrayList<>();
        for (int j = 0; j < 3; j++) {
            FoodModel foodModel = new FoodModel();
            foodModel.id = 0; // i set primary key 0, so in list should be 3 but when insert should be JUST one
            foodModel.packId = i;
            foodModel.name = "Food " + new Random().nextInt(100);
            foodModel.stock = new Random().nextInt(100);
            foodModel.price = new Random().nextInt(100);
            foodModel.image = "hrrp";
            foodModel.calorie = new Random().nextInt(100);
            foodModel.createTime = System.nanoTime();
            foods.add(foodModel);
        }
        packModel.foods.addAll(foods);
        packs.add(packModel);
    }

    insertdb(packs);
}

As you see a List of PackModel, and each PackModel have their food items. So, i write in Realm like below code.

private void insertdb(final List<PackModel> items) {
    new AsyncTask<Void, Void, List<PackObject>>() {
        @Override
        protected List<PackObject> doInBackground(Void... params) {
            final List<PackObject> packsObject = new ArrayList<>();
            for (int i = 0; i < items.size(); i++) {
                PackObject packObject = new PackObject();
                packObject.id = items.get(i).id;
                packObject.name = items.get(i).name;

                List<FoodObject> foodsObject = new ArrayList<>();
                for (int j = 0; j < items.get(i).foods.size(); j++) {
                    FoodObject foodObject = new FoodObject();
                    foodObject.id = items.get(i).foods.get(j).id;
                    foodObject.name = items.get(i).foods.get(j).name;
                    foodObject.createdTime = items.get(i).foods.get(j).createTime;

                    foodsObject.add(foodObject);
                }
                packObject.foods.addAll(foodsObject);
                packsObject.add(packObject);
            }

            Realm realm = Realm.getInstance(RealmApplication.getRealmConfiguration());
            realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    realm.copyToRealmOrUpdate(packsObject);
                }
            });

            return realm.copyFromRealm(realm.where(PackObject.class).findAll());

        }

        @Override
        protected void onPostExecute(List<PackObject> items) {
            super.onPostExecute(items);
            Log.d("Test", "");
        }
    }.execute();
}

I got multiple FoodObject in each PackObject, what i am wrong here? i also use realm.beginTransaction. realm.beginTransaction is just a same like execute*, the difference just execute* are thread safe.

i also use realm.insertOrUpdate(obj), but just have same result.

NOTE: I have read realm documentation about it. So dont judge me not read their documentation.

this my repot for the code https://github.com/radityagumay/realm-bug

enter image description here

Thanks

raditya gumay
  • 2,951
  • 3
  • 17
  • 24

0 Answers0