requery / requery

requery - modern SQL based query & persistence for Java / Kotlin / Android
Apache License 2.0
3.14k stars 246 forks source link

ManyToOne relations not refreshing when loading from database #452

Open loredan opened 7 years ago

loredan commented 7 years ago

I've got the bug when I'm adding an object to the database, but the other object that references the added one with a ManyToOne annotation does not refresh even when I load it from database using SELECT. Here is a repo with a simple project that illustrates that behavior: requery-scratchpad

Here is the code:

Client client = Requery.getDataStore().select(Client.class).get().first();

System.out.println(client.getPayments().size());

Payment test = new Payment();
test.setClient(client);
test.setAmount(0);
test.setDate(0);
Requery.getDataStore().insert(test).blockingGet();

System.out.println(client.getPayments().size());
System.out.println(Requery.getDataStore().select(Client.class).get().first().getPayments().size());

client = Requery.getDataStore().refresh(client).blockingGet();

System.out.println(client.getPayments().size());
System.out.println(Requery.getDataStore().select(Client.class).get().first().getPayments().size());

Database attached to the project has one Client object and no Payment objects, so the first output (line 3) is 0, as expected. Then I create new Payment object and add it to the database. Second output (line 11) is 0, which is to be expected since the list is already loaded, however the third one (line 12) requests new Client object from the database, but still prints 0. After refreshing the object, both outputs (line 16 and 17) are 1.

I guess it is some kind of optimization, reducing the number of requests to the database, but, in my opinion, this behavior is far from obvious. Maybe there is another method to add this kind of objects to the database without having to perform refresh, but I haven't seen that in the wiki, so I did it like I used to do.

npurushe commented 7 years ago

There are a couple of options: 1) Add the payment to the client payments collection 2) Refresh that one collection only (store.refresh(client, Client.PAYMENTS)

At the moment, selecting the Client again through a query will only refresh the client column fields and not it's payments. It maybe possible to do 1) automatically for you, this is something I'm looking into.

MrOnyszko commented 7 years ago

Hi! Is it possible to do refresh all OneToMany relationships in easy way?

Let say we have Client (as above) entity that have list of Payment entities and that Payment have another one list of Entry. In that case when we'll select an Client by key from database the list of Payment will empty. If we refresh that list of payments in client entity and then select that client again it will be not empty but list of entries will be empty.