简体   繁体   中英

Realm Query Returns Incomplete Results Set In Android

I have been having a very unusual behavior when using Realm to insert and read/query data. Here is what is happening to be precise:

Initial Status

When I start to insert data to the database, everything works fine. I have the following code to handle autoIncrementingId since I have not found a version of Realm that offers this out of the box!

CashOrder cashOrder = new CashOrder();

realm.beginTransaction();

int lastCashOrderId;
RealmResults<CashOrder> cashOrders = realm.where(CashOrder.class).findAll();

cashOrders.sort("id", Sort.ASCENDING);

if (cashOrders.isEmpty()){
    cashOrder.setId("0");
}else{
    lastCashOrderId = Integer.parseInt(cashOrders.last().getId());
    cashOrder.setId(String.valueOf(lastCashOrderId + 1));
}

//the rest of the code here 

//then copyToRealm here;

realm.copyToRealm(cashOrder);
realm.commitTransaction();

The problem

Insertion of data into the database works just fine but the moment the id value reaches 10 - implying 11 items in the table since my id starts at (0) , I get a Realm Primary Key Exception which basically complains that I am trying to add an already existing object.

I am explicitly calling realm.copyToRealm(obj) instead of realm.copyToRealmOrUpdate(obj) because that is what I want to do. Updates only are allowed when doing an Edit .

I am stuck here and I can't seem to figure out what is causing this issue!

More information

I am using:

compile 'io.realm:realm-android:0.87.4'

I will truly appreciate your help on this! Thanks in advance!

It's because your ID is a STRING and therefore it's ordered as 1 , 10 , 2 , 3 , ... 9 .

This means when you evaluate the "next ID" when you had already inserted "10" ,

lastCashOrderId = Integer.parseInt(cashOrders.last().getId()); 

lastCashOrderId will be 9, and you'll be inserting 10 again.

Solution: use long id for longs, or re-think your auto-increment IDs (f.ex. use UUID.randomString() or something)

PS you should use findAllSorted() instead of findAll().sort() for consistent behavior when you update to the newer Realm versions.

EDIT: please use long newId = realm.where(CashOrder.class).max("age").longValue() + 1; to evaluate the new ID, and do this while you're in a transaction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM