I am having problems with ObjectBox in my Android app. Everything works, except for this issue, so I know my entity classes are OK.
It's an inventory that makes it possible to do inventories of multiple shops (stores). Each InventoryItem is a product that was scanned when doing the inventory. When the inventory is concluded, one or more text files are generated from the data in the box.
One file is generated for each shop, so I have this code to find which distinct shops were inventoried:
Box<InventoryItem> box = app.getBoxStore().boxFor(InventoryItem.class);
long[] shopIds = box.query()
.build()
.property(InventoryItem_.shopId)
.distinct()
.findLongs();
I get the following when this code runs (only relevant part of the stacktrace):
Caused by: java.lang.IllegalArgumentException: Property "shopId" is of type Relation, but we expected a property of type Long in this context
at io.objectbox.query.PropertyQuery.nativeFindLongs(Native Method)
at io.objectbox.query.PropertyQuery$2.call(PropertyQuery.java:213)
at io.objectbox.query.PropertyQuery$2.call(PropertyQuery.java:210)
at io.objectbox.BoxStore.callInReadTx(BoxStore.java:709)
at io.objectbox.BoxStore.callInReadTxWithRetry(BoxStore.java:654)
at io.objectbox.query.Query.callInReadTx(Query.java:273)
at io.objectbox.query.PropertyQuery.findLongs(PropertyQuery.java:210)
at br.com.donadio.inventario.view.ExportDialog$GenerateFilesAsync.doInBackground(ExportDialog.java:132)
at br.com.donadio.inventario.view.ExportDialog$GenerateFilesAsync.doInBackground(ExportDialog.java:104)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
I also tried using .property(InventoryItem_.shop.targetIdProperty) in the query, but it gives the exact same error. I can't find another way to do this, nor a way to fix my code.
I'm using AndroidX (not that it should matter) and my project is correctly setup for it. MinSdk is 19, MaxSdk is 28, targetSdk is 28. ObjectBox version is 2.2.0. Debugging on a device running Android 7.1.1.
These are the relevant entities:
@Entity
public class InventoryItem
{
@Id
public long id;
public String operator;
public ToOne<Area> area;
public long areaId; // expose relationship target ID
public ToOne<Product> product;
public long productId; // expose relationship target ID
public ToOne<Shop> shop;
public long shopId; // expose relationship target ID
public Date timestamp;
// ...
}
@Entity
public class Shop
{
@Id(assignable=true)
public long id;
@Index @Unique
public String name;
@Backlink
public ToMany<InventoryItem> inventoryItems;
// ...
}
After looking a lot for an answer in ObjectBox's GitHub and here, I came up with a solution, based on this answer on the project's GitHub:
List<InventoryItem> items = box.getAll();
ArrayList<Shop> shops = new ArrayList<>();
for (InventoryItem item : items)
{
Shop shop = item.shop.getTarget();
if (!shops.contains(shop))
shops.add(shop);
}
So, we just find everything and then iterate through the list, getting distinct objects in an ArrayList (or I could just get the Id's into a long[]) . Just a handful more lines of code...
Still, I consider that a bug in ObjectBox's implementation, as it's returning a relationship instead of a property on a long attribute. I'm opening an issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With