public abstract class QueryJObjectContainer extends ReloadableJObjectContainer
Container
backed by Permazen
Java model objects acquired by performing
a transactional query and copying out the results into a SnapshotJTransaction
.
The subclass method queryForObjects() performs the query returning the backing objects
within an already-opened transaction. The Item
s in the container are backed by in-memory copies
of the returned JObject
s; these live inside a SnapshotJTransaction
and therefore may persist indefinitely
after the query transaction closes.
Instances may be (re)loaded at any time by invoking reload()
. During reload, the container opens a new
JTransaction
, queries for objects using queryForObjects()
, and copies each returned
object into the associated SnapshotJTransaction
via copyWithRelated()
,
which copies the object and any related objects necessary for resolving container properties. The set of related
objects associated with an object is determined by getRelatedObjects()
; by default,
this is all directly referenced objects. Subclasses may override to customize.
It is up to queryForObjects()
to determine what and how many objects are returned, their
sort order, etc. Any objects returned by queryForObjects()
that are not instances of the
container's configured type are ignored.
@ProvidesProperty
Limitations
The use of @ProvidesProperty
methods has certain implications.
First, if the method reads any of the object's field(s) via their Java getter methods (as would normally be expected),
this will trigger a schema upgrade of the object if needed; however, this schema upgrade will occur in the
container's in-memory SnapshotJTransaction
rather than in a real database transaction, so the
JObjectContainer.VERSION_PROPERTY
will return a different schema version from what's in the database. The automatic schema
upgrade can be avoided if desired by reading the field using the appropriate JTransaction
field access method
(e.g., JTransaction.readSimpleField()
) and being prepared to handle a
UnknownFieldException
if/when the object has an older schema version that does not contain
the requested field.
Secondly, because the values of reference fields (including complex sub-fields) are displayed using reference labels,
and these are typically derived from the referenced object's fields, those indirectly referenced objects need to be
copied into the container's SnapshotJTransaction
as well. The easiest way to ensure these indirectly
referenced objects are copied is by overriding getRelatedObjects()
as described above.
JObjectContainer.ObjFieldPropertyDef, JObjectContainer.ObjIdPropertyDef, JObjectContainer.ObjPropertyDef<T>, JObjectContainer.ObjTypePropertyDef, JObjectContainer.ObjVersionPropertyDef, JObjectContainer.RefLabelPropertyDef
AbstractInMemoryContainer.BaseItemAddEvent, AbstractInMemoryContainer.BaseItemRemoveEvent
AbstractContainer.BaseItemSetChangeEvent, AbstractContainer.BasePropertySetChangeEvent
Container.Editor, Container.Filter, Container.Filterable, Container.Hierarchical, Container.Indexed, Container.ItemSetChangeEvent, Container.ItemSetChangeListener, Container.ItemSetChangeNotifier, Container.Ordered, Container.PropertySetChangeEvent, Container.PropertySetChangeListener, Container.PropertySetChangeNotifier, Container.SimpleFilterable, Container.Sortable, Container.Viewer
Container.Indexed.ItemAddEvent, Container.Indexed.ItemRemoveEvent
jdb, log, OBJECT_ID_PROPERTY, REFERENCE_LABEL_PROPERTY, TYPE_PROPERTY, VERSION_PROPERTY
Modifier | Constructor and Description |
---|---|
protected |
QueryJObjectContainer(Permazen jdb,
Class<?> type)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
JObject |
copyWithRelated(JObject target,
JTransaction dest,
CopyState copyState)
Copy the given database object, and any related objects needed by any
@ProvidesProperty -annotated methods,
into the specified transaction. |
protected Iterable<? extends JObject> |
getRelatedObjects(JObject jobj)
Find objects related to the specified object that are needed by any
@ProvidesProperty -annotated
methods. |
protected abstract Iterator<? extends JObject> |
queryForObjects()
Query for the database objects that will be used to fill this container.
|
void |
reload()
(Re)load this container.
|
connect, disconnect, reloadAfterCommit
canSort, doInTransaction, getKeyFor, getOrderedPropertyNames, getPropertyValue, getType, load, load, setType, sort, updateItem
generateItemId, getItemIdFor, getItemIdForSame, getJavaObject, resetItemIds
addContainerFilter, addContainerFilter, afterReload, createBackedItem, getContainerFilters, getContainerProperty, getContainerPropertyIds, getItemIds, getPropertyExtractor, getSortableContainerPropertyIds, getType, getUnfilteredItem, internalRemoveAllItems, removeAllContainerFilters, removeContainerFilter, removeContainerFilters, setProperties, setProperty, setPropertyExtractor, sort
addContainerProperty, addFilter, addItem, addItem, addItemAfter, addItemAfter, addItemAt, addItemAt, addItemSetChangeListener, addListener, containsId, doFilterContainer, doSort, filterAll, fireItemAdded, fireItemRemoved, fireItemsAdded, fireItemsRemoved, firstItemId, getAllItemIds, getFilteredItemIds, getFilters, getFirstVisibleItem, getIdByIndex, getItem, getItemIds, getItemSorter, getSortablePropertyIds, getVisibleItemIds, hasContainerFilters, indexOfId, internalAddItemAfter, internalAddItemAt, internalAddItemAtEnd, internalRemoveItem, isFiltered, isFirstId, isLastId, isPropertyFiltered, lastItemId, nextItemId, passesFilters, prevItemId, registerNewItem, removeAllFilters, removeAllItems, removeContainerProperty, removeFilter, removeFilters, removeItem, removeItemSetChangeListener, removeListener, setAllItemIds, setFilteredItemIds, setFilters, setItemSorter, size, sortContainer
addListener, addPropertySetChangeListener, fireContainerPropertySetChange, fireContainerPropertySetChange, fireItemSetChange, fireItemSetChange, getItemSetChangeListeners, getListeners, getPropertySetChangeListeners, removeListener, removePropertySetChangeListener, setItemSetChangeListeners, setPropertySetChangeListeners
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
addItemAfter, addItemAfter, firstItemId, isFirstId, isLastId, lastItemId, nextItemId, prevItemId
addContainerProperty, addItem, addItem, containsId, getItem, removeAllItems, removeContainerProperty, removeItem, size
protected QueryJObjectContainer(Permazen jdb, Class<?> type)
jdb
- Permazen
databasetype
- type restriction, or null for no restrictionIllegalArgumentException
- if jdb
is nullpublic void reload()
This creates a new JTransaction
, invokes queryForObjects()
to query for backing objects,
copies them into an in-memory SnapshotJTransaction
via copyWithRelated()
,
and builds the container from the result.
reload
in class ReloadableJObjectContainer
public JObject copyWithRelated(JObject target, JTransaction dest, CopyState copyState)
@ProvidesProperty
-annotated methods,
into the specified transaction.
The implementation in JObjectContainer
copies jobj
, and all of jobj
's related objects returned
by getRelatedObjects()
, via JTransaction.copyTo(JTransaction, CopyState, Iterable)
.
target
- the object to copy, or null (ignored)dest
- destination transactioncopyState
- tracks what's already been copiedtarget
in dest
, or null if target
is nullgetRelatedObjects()
protected Iterable<? extends JObject> getRelatedObjects(JObject jobj)
@ProvidesProperty
-annotated
methods.
This defines all of the other objects on which any container property of jobj
may depend.
These related objects will copied along with obj
into the container's
SnapshotJTransaction
when the container is (re)loaded.
The implementation in JObjectContainer
returns all objects that are directly referenced by jobj
,
delegating to Permazen.getReferencedObjects()
.
Subclasses may override this method to refine the selection.
jobj
- the object being copiedIterable
of additional objects to be copied, or null for none; any null values are ignoredIllegalArgumentException
- if jobj
is nullprotected abstract Iterator<? extends JObject> queryForObjects()
A JTransaction
will be open in the current thread when this method is invoked.
Copyright © 2022. All rights reserved.