Realm: размер заполненного RealmList в RealmObject равен нулю

Сценарий:
У меня есть модель (DBBasket) для локального сохранения, количество добавленных продуктов и сами продукты.
Когда пользователь нажимает кнопку + под миниатюрой каждого товара

  • Я увеличиваю totalQuantity в Product,
  • Добавление продукта в DBBasket,
  • Установите totalProducts, который я получаю с сервера, в DBBasket тоже.

Коды в кнопке +:

holder.HomeProductBindGrid.thatPlusButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final Product productIns = mProductsList.get(holder.getAdapterPosition());
            mRealm = mRealmManager.getLocalInstance();
            mRealm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(@NonNull Realm realm) {
                    mProductRealm = realm.where(Product.class).equalTo(ProductFields.UNIQUE_ID, productIns.getUniqueId()).findFirst();
....


realm = mRealmManager.getLocalInstance();
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        String totalNumberOfItemsInBasket = parseDataFromServer(ServerResponse, "numberOfProducts");
        if (totalNumberOfItemsInBasket.matches("")) {
            totalNumberOfItemsInBasket = "0";
        }

        Product product = realm.where(Product.class).equalTo(ProductFields.UNIQUE_ID, prod.getUniqueId()).findFirst();
        if (product == null) {
            product = realm.createObject(Product.class, mProductRealm.getUniqueId());
        }

        if (product != null) {
            if (product.totalQuantity.get() == null) {
                product.totalQuantity.set(0);
                product.totalQuantity.increment(countOrder);
            } else {
                product.totalQuantity.increment(countOrder);
            }
            realm.insertOrUpdate(product);

            DBBasket dbBasket = realm.where(DBBasket.class).findFirst();
            if (dbBasket == null) {
                dbBasket = realm.createObject(DBBasket.class);
            }

            dbBasket.getProducts().add(product);
            dbBasket.setTotalProducts(totalNumberOfItemsInBasket);
            realm.insertOrUpdate(dbBasket);
            Log.wtf("productRealm", dbBasket.getProducts().get(0).getUniqueId() + "");// It shows the UID correctly.
        }
    }
});

По какой-то причине я очищаю Product при уничтожении активности, но не DBBasket:

Realm realm = mRealmManager.getLocalInstance();
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(@NonNull Realm realm) {
            realm.delete(Product.class);
        }
    });

Каждый раз, когда пользователь заходит на главную, я получаю список товаров с сервера и вставляю их в локальную БД:

for (int j = 0; j < receivedProductsFromServer.getLength(); j++) {
    final Product product = new Product(...);

    product.setUniqueId(Utils.UniqueIdMaker());

    realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(@NonNull Realm realm) {
          Product productRealm = realm.where(Product.class).equalTo(ProductFields.UNIQUE_ID, product.getUniqueId()).findFirst();
          if (productRealm == null) {
            realm.insert(product);
          }
    }
});

Проблема.
Теперь для тех продуктов, которые ранее были добавлены в DBBasket, я хочу показать их totalQuantity перед этим +.
Поэтому я изменен приведенный выше код фрагмента на:

for (int j = 0; j < receivedProductsFromServer.getLength(); j++) {
    final Product product = new Product(...);

    product.setUniqueId(Utils.UniqueIdMaker());

    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(@NonNull Realm realm) {
            Product productRealm = realm.where(Product.class).equalTo(ProductFields.UNIQUE_ID, product.getUniqueId()).findFirst();
            if (productRealm == null) {
                DBBasket dbBasketRealm = realm.where(DBBasket.class).findFirst();

                if(dbBasketRealm != null) {
                    RealmList<Product> productInBasket = dbBasketRealm.getProducts(); //Size() is zero!!!

                    RealmResults<Product> productFiltered = productInBasket.where().contains(ProductFields.UNIQUE_ID, product.getUniqueId()).findAll();
                    Product p = productFiltered.get(0);

                    if(p != null) {
                        product.totalQuantity.set(0);
                        product.totalQuantity.increment(Integer.valueOf(p.getQuantity()));
                    } else Log.wtf("productRealm", "productFiltered is Null.");
                }
                realm.insert(product);
            }
        }
    });

Но это не сработало! и размер dbBasketRealm.getProducts() равен нулю.


Изменить:
Кнопка + в режиме отладки: + Кнопка в режиме отладки

dbBasketRealm.getProducts() в режиме отладки:
dbBasketRealm.getProducts() в режиме отладки


Модель DBBasket:

public class DBBasket extends RealmObject{
    public String totalProducts;
    public RealmList<Product> products;

    public DBBasket() {}
}

Модель продукта:

public class Product extends RealmObject implements Observable {
    @PrimaryKey
    @Required
    private String uniqueId;
    public final MutableRealmInteger totalQuantity = MutableRealmInteger.valueOf(0);

    public Product() {}
}

person Dr.jacky    schedule 28.02.2018    source источник
comment
@TimCastelijns, если вы имеете в виду DBBasket, я впервые заполняю его с помощью кнопки +. DBBasket dbBasket = realm.where(DBBasket.class).findFirst(); if (dbBasket == null) {dbBasket = realm.createObject(DBBasket.class);} dbBasket.getProducts().add(product);. И сделайте запрос на onCreate например DBBasket dbBasketRealm = realm.where(DBBasket.class).findFirst();.   -  person Dr.jacky    schedule 28.02.2018
comment
RealmList управляемого объекта не может быть нулевым. О_О   -  person EpicPandaForce    schedule 28.02.2018
comment
@EpicPandaForce Извините, мой плохой. Я изменил название вопроса и добавил два скриншота режима отладки. dbBasketRealm.getProducts() не равно нулю; размер его нулевой! Но как?! Я заполнил его кнопкой + и добавил в Realm раньше.   -  person Dr.jacky    schedule 03.03.2018
comment
@EpicPandaForce Когда я не очищаю модель Product (realm.delete(Product.class)), размер getProducts на DBBasket больше нуля. Разве у DBBasket нет своего Продукта?! И когда я убираю Product модель, она чистит и на DBBasket тоже?!   -  person Dr.jacky    schedule 03.03.2018
comment
Если вы удалите Продукты из Царства, все ссылки, указывающие на него, также станут недействительными. Это вполне ожидаемое поведение, если вы вызываете realm.delete(Product.class)   -  person EpicPandaForce    schedule 03.03.2018


Ответы (1)


Получить ранее добавленные товары в корзину, с сервера. Затем снова добавьте их в локальную базу данных. Что-то вроде приведенного ниже фрагмента кода в OnCreate, например:

for (int i = 0; i < receivedFromServer.getLength(); i++) {

realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(@NonNull Realm realm) {
        Product productRealm = realm.where(Product.class).equalTo(ProductFields.UNIQUE_ID, receivedFromServer[i].getUniqueId()).findFirst();

        if (productRealm != null) {
            productRealm.setTotalQuantity(quantity));

            DBBasket dbBasket = realm.where(DBBasket.class).findFirst();
            if (dbBasket == null) {
                dbBasket = realm.createObject(DBBasket.class);
            }

            RealmList<Product> productRealmList = dbBasket.getProducts();
            productRealmList.add(productRealm);
            dbBasket.products = productRealmList;
            dbBasket.setProducts(productRealmList);
            dbBasket.totalProductsSetZero();
            dbBasket.setTotalProducts(quantity));
            realm.insertOrUpdate(dbBasket);
        }
    }
});
person Dr.jacky    schedule 11.03.2018