Lukas Knuth Lukas Knuth - 3 months ago 27
Java Question

Eager-Load all entries of a List<Ref<T>>

I currently use this pattern to store lists of types that are also Objectify entities:

@Entity
class Test{
private List<Ref<T>> data = new ArrayList<>();

public List<T> getTees(){
List<T> tmp = new ArrayList<>(this.data.size()); // Is the entire list loaded here?
for (Ref<T> d : this.data) {
tmp.add(d.get()); // or every single entry here??
}
return tmp;
}
}


The question is: will the first time the
data
-field is used load the entire list (the data that
Ref
"points" to) from the data-storage, or will the
Ref<T>.get()
-method load each entry individually?

If so, how can a bulk-load the entire list at once?

Note: I don't always need the list, that's why it doesn't have the
@Load
-annotation.

Answer

Objectify will not load anything referenced unless you .get() it explicitly, this results in individual fetches, or you tell it to auto load all the things via @Load. That speeds up loading overall because it can batch process the request instead of forming several individual ones.

If by "I don't always need the list" you mean that you have distinct cases of "need" vs "not need", take a look at load groups, essentially a way to turn the @Load annotation on or off.

https://code.google.com/p/objectify-appengine/wiki/Entities#Relationships has examples like yours https://code.google.com/p/objectify-appengine/wiki/BasicOperations#Load_Groups to turn on/off auto loading


There is btw a way to load a list of Refs in a single batch using
Map<Key<T>,T> Loader#refs(Iterable<Ref<T>> refs)

public List<T> getTees(){
    Collection<T> values = ofy().load().refs(data).values();
    return new ArrayList<T>(values);
}