问题
Scenario:
I have a model(DBBasket) to persist locally, the number of added products and products itself.
When the user clicks on the + button under each product thumbnail
- I'm increasing
totalQuantity
inProduct
, - Adding the product to the
DBBasket
, - Set
totalProducts
which I get from server, inDBBasket
too.
Codes in + button:
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.
}
}
});
Cause of some reason, I clean the Product
on Activity Destroy, but not DBBasket
:
Realm realm = mRealmManager.getLocalInstance();
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(@NonNull Realm realm) {
realm.delete(Product.class);
}
});
Each time the user comes to the main page, I receive the list of products from the server, and insert them to the local DB:
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);
}
}
});
Problem:
Now, for those products which added previously to the DBBasket
, I want to show their totalQuantity
in front of that +.
So I've changed above snippet code to:
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);
}
}
});
But didn't work! and dbBasketRealm.getProducts()
size is zero.
Edit:
+ Button on Debug mode:
dbBasketRealm.getProducts()
on Debug mode:
DBBasket model:
public class DBBasket extends RealmObject{
public String totalProducts;
public RealmList<Product> products;
public DBBasket() {}
}
Product model:
public class Product extends RealmObject implements Observable {
@PrimaryKey
@Required
private String uniqueId;
public final MutableRealmInteger totalQuantity = MutableRealmInteger.valueOf(0);
public Product() {}
}
回答1:
Get the previously added products in the basket, from the server. Then add them again to the local database. Something like below snippet code in OnCreate
for example:
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);
}
}
});
来源:https://stackoverflow.com/questions/49029813/realm-the-size-of-filled-realmlist-in-realmobject-is-zero