Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ObjectBox (Java): Property query on a relation doesn't work

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;

    // ...
}
like image 778
fdonadio Avatar asked Jul 10 '26 11:07

fdonadio


1 Answers

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.

like image 64
fdonadio Avatar answered Jul 12 '26 00:07

fdonadio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!