Skip to content

Commit 997630e

Browse files
Docs: add lazy-loading details to ToMany, fix eager missing sentence
1 parent 3ad0810 commit 997630e

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

objectbox-java/src/main/java/io/objectbox/query/QueryBuilder.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,7 @@ public <TARGET> QueryBuilder<TARGET> backlink(RelationInfo<TARGET, ?> relationIn
425425

426426
/**
427427
* Specifies relations that should be resolved eagerly.
428-
* This prepares the given relation objects to be preloaded (cached) avoiding further get operations from the db.
429-
* A common use case is prealoading all
428+
* This prepares the given relation objects to be preloaded (cached) avoiding further get operations from the database.
430429
*
431430
* @param relationInfo The relation as found in the generated meta info class ("EntityName_") of class T.
432431
* @param more Supply further relations to be eagerly loaded.

objectbox-java/src/main/java/io/objectbox/relation/ToMany.java

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import io.objectbox.BoxStore;
3636
import io.objectbox.Cursor;
3737
import io.objectbox.InternalAccess;
38+
import io.objectbox.annotation.Backlink;
3839
import io.objectbox.annotation.apihint.Beta;
3940
import io.objectbox.annotation.apihint.Experimental;
4041
import io.objectbox.annotation.apihint.Internal;
@@ -43,21 +44,28 @@
4344
import io.objectbox.internal.ReflectionCache;
4445
import io.objectbox.internal.ToManyGetter;
4546
import io.objectbox.internal.ToOneGetter;
47+
import io.objectbox.query.QueryBuilder;
4648
import io.objectbox.query.QueryFilter;
4749
import io.objectbox.relation.ListFactory.CopyOnWriteArrayListFactory;
4850

4951
import static java.lang.Boolean.TRUE;
5052

5153
/**
52-
* A List representing a to-many relation.
53-
* It tracks changes (adds and removes) that can be later applied (persisted) to the database.
54-
* This happens either on {@link Box#put(Object)} of the source entity of this relation or using
55-
* {@link #applyChangesToDb()}.
54+
* A lazily loaded {@link List} of target objects representing a to-many relation, a unidirectional link from a "source"
55+
* entity to multiple objects of a "target" entity.
5656
* <p>
57-
* If this relation is a backlink from a {@link ToOne} relation, a DB sync will also update ToOne objects
58-
* (but not vice versa).
57+
* It tracks changes (adds and removes) that can be later applied (persisted) to the database. This happens either when
58+
* the object that contains this relation is put or using {@link #applyChangesToDb()}. For some important details about
59+
* applying changes, see the notes about relations of {@link Box#put(Object)}.
5960
* <p>
60-
* ToMany is thread-safe by default (only if the default {@link java.util.concurrent.CopyOnWriteArrayList} is used).
61+
* The objects are loaded lazily on first access of this list, and then cached. The database query runs on the calling
62+
* thread, so avoid accessing this from a UI or main thread. Subsequent calls to any method, like {@link #size()}, do
63+
* not query the database, even if the relation was changed elsewhere. To get the latest data {@link Box#get} the source
64+
* object again or use {@link #reset()} before accessing the list again.
65+
* <p>
66+
* It is possible to preload the list when running a query using {@link QueryBuilder#eager}.
67+
* <p>
68+
* ToMany is thread-safe by default (may not be the case if {@link #setListFactory(ListFactory)} is used).
6169
*
6270
* @param <TARGET> Object type (entity).
6371
*/
@@ -482,8 +490,10 @@ public <T> T[] toArray(T[] array) {
482490
}
483491

484492
/**
485-
* Resets the already loaded entities so they will be re-loaded on their next access.
486-
* This allows to sync with non-tracked changes (outside of this ToMany object).
493+
* Resets the already loaded (cached) objects of this list, so they will be re-loaded when accessing this list
494+
* again.
495+
* <p>
496+
* Use this to sync with changes to this relation or target objects made outside of this ToMany.
487497
*/
488498
public synchronized void reset() {
489499
entities = null;
@@ -540,12 +550,14 @@ else if (delta > 0)
540550
}
541551

542552
/**
543-
* Applies (persists) tracked changes (added and removed entities) to the target box
544-
* and/or updates standalone relations.
545-
* Note that this is done automatically when you put the source entity of this to-many relation.
546-
* However, if only this to-many relation has changed, it is more efficient to call this method.
553+
* Saves changes (added and removed entities) made to this relation to the database. For some important details, see
554+
* the notes about relations of {@link Box#put(Object)}.
555+
* <p>
556+
* Note that this is called already when the object that contains this ToMany is put. However, if only this ToMany
557+
* has changed, it is more efficient to just use this method.
547558
*
548-
* @throws IllegalStateException If the source entity of this to-many relation was not previously persisted
559+
* @throws IllegalStateException If the object that contains this ToMany has no ID assigned (it must have been put
560+
* before).
549561
*/
550562
public void applyChangesToDb() {
551563
long id = relationInfo.sourceInfo.getIdGetter().getId(entity);
@@ -571,7 +583,7 @@ public void applyChangesToDb() {
571583
/**
572584
* Returns true if at least one of the entities matches the given filter.
573585
* <p>
574-
* For use with {@link io.objectbox.query.QueryBuilder#filter(QueryFilter)} inside a {@link QueryFilter} to check
586+
* For use with {@link QueryBuilder#filter(QueryFilter)} inside a {@link QueryFilter} to check
575587
* to-many relation entities.
576588
*/
577589
@Beta
@@ -589,7 +601,7 @@ public boolean hasA(QueryFilter<TARGET> filter) {
589601
/**
590602
* Returns true if all of the entities match the given filter. Returns false if the list is empty.
591603
* <p>
592-
* For use with {@link io.objectbox.query.QueryBuilder#filter(QueryFilter)} inside a {@link QueryFilter} to check
604+
* For use with {@link QueryBuilder#filter(QueryFilter)} inside a {@link QueryFilter} to check
593605
* to-many relation entities.
594606
*/
595607
@Beta
@@ -694,6 +706,17 @@ public boolean internalCheckApplyToDbRequired() {
694706
}
695707
}
696708

709+
/**
710+
* Modifies the {@link Backlink linked} ToMany relation of added or removed target objects and schedules put by
711+
* {@link #internalApplyToDb} for them.
712+
* <p>
713+
* If {@link #setRemoveFromTargetBox} is true, removed target objects are scheduled for removal instead of just
714+
* updating their ToMany relation.
715+
* <p>
716+
* If target objects are new, schedules a put if they were added, but never if they were removed from this relation.
717+
*
718+
* @return Whether there are any target objects to put or remove.
719+
*/
697720
private boolean prepareToManyBacklinkEntitiesForDb(long entityId, IdGetter<TARGET> idGetter,
698721
@Nullable Map<TARGET, Boolean> setAdded, @Nullable Map<TARGET, Boolean> setRemoved) {
699722
ToManyGetter<TARGET, Object> backlinkToManyGetter = relationInfo.backlinkToManyGetter;
@@ -738,6 +761,9 @@ private boolean prepareToManyBacklinkEntitiesForDb(long entityId, IdGetter<TARGE
738761
}
739762
}
740763

764+
/**
765+
* Like {@link #prepareToManyBacklinkEntitiesForDb} but for the linked ToOne relation.
766+
*/
741767
private boolean prepareToOneBacklinkEntitiesForDb(long entityId, IdGetter<TARGET> idGetter,
742768
@Nullable Map<TARGET, Boolean> setAdded, @Nullable Map<TARGET, Boolean> setRemoved) {
743769
ToOneGetter<TARGET, Object> backlinkToOneGetter = relationInfo.backlinkToOneGetter;

0 commit comments

Comments
 (0)