public interface JObject
Permazen
Java model objects.
All Permazen
database objects are instances of runtime-generated sub-classes of user-provided Java model types.
These generated subclasses will always implement this interface, providing convenient access to database operations.
Therefore, it is convenient to declare Java model classes abstract
and implements JObject
.
However, this is not strictly necessary; all of the methods declared here ultimately delegate to one of the
JTransaction
support methods.
Object Identity and State
Every JObject
has a unique 64-bit object identifier, represented as an ObjId
.
All JObject
instances are permanently associated with a specific
transaction, and are the unique representatives for their corresponding ObjId
in that transaction. All field state derives from the associated transaction.
There are two types of transactions: normal transactions reflecting an open transaction on the underlying key/value database, and snapshot transactions, which are in-memory containers of object data. Snapshot transactions are fully functional, supporting index queries, object versioning, etc.
Copying Objects
This interface provides methods for copying a graph of objects between transactions, for example, from an open
key/value database transaction into an in-memory snapshot transaction ("copy out"), or vice-versa ("copy in").
A graph of objects can be copied by specifying a starting object and either a list of reference paths, or
a cascade name (see @JField
). Object ID's can be remapped during
the copy if necessary, e.g., to ensure existing objects are not overwritten (see CopyState
).
JTransaction
Modifier and Type | Method and Description |
---|---|
default JObject |
cascadeCopyIn(String cascadeName,
boolean clone)
Copy this instance and all objects reachable from it via the specified cascade
into the transaction associated with the current thread.
|
default JObject |
cascadeCopyOut(String cascadeName,
boolean clone)
Copy this instance and all objects reachable from it via the specified cascade
into the associated in-memory snapshot transaction.
|
default JObject |
cascadeCopyTo(JTransaction dest,
String cascadeName,
boolean clone)
Copy this instance and all objects reachable from it via the specified cascade into the specified destination transaction.
|
default JObject |
cascadeCopyTo(JTransaction dest,
String cascadeName,
int recursionLimit,
boolean clone)
Copy this instance and all objects reachable from it via the specified cascade into the specified destination transaction.
|
default JObject |
copyIn(String... refPaths)
Copy this instance, and other instances it references through the specified
refPaths (if any),
into the transaction associated with the current thread. |
default JObject |
copyOut(String... refPaths)
Copy this instance and other instances it references through the specified reference paths (if any)
into the associated in-memory snapshot transaction.
|
default JObject |
copyTo(JTransaction dest,
CopyState copyState,
String... refPaths)
Copy this instance, and other instances it references through the specified reference paths, into the
specified destination transaction.
|
default boolean |
delete()
Delete this instance, if it exists, in this instance's associated transaction.
|
default boolean |
exists()
Determine whether this instance still exists in its associated transaction.
|
default <R> NavigableSet<R> |
findReferring(Class<R> type,
String fieldName)
Find all objects of the given type referring to this object through the specified reference field.
|
default JClass<?> |
getJClass()
|
Class<?> |
getModelClass()
Get the original Java model class of which this
JObject is an instance. |
ObjId |
getObjId()
Get this instance's unique Permazen object identifier.
|
default int |
getSchemaVersion()
Get this instance's current schema version.
|
JTransaction |
getTransaction()
Get this instance's associated
JTransaction . |
default boolean |
isSnapshot()
Determine whether this instance is a normal instance or is an in-memory "snapshot" instance associated
with a
SnapshotJTransaction . |
default boolean |
recreate()
Recreate a deleted instance, if it does not exist, in its associated transaction.
|
void |
resetCachedFieldValues()
Reset cached simple field values.
|
default void |
revalidate(Class<?>... groups)
Add this instance to the validation queue for validation in its associated transaction.
|
default boolean |
upgrade()
Update the schema version of this instance, if necessary, so that it matches the schema version
of its associated transaction.
|
ObjId getObjId()
This method always succeeds, even if the object does not exist.
default int getSchemaVersion()
DeletedObjectException
- if this object does not exist in the JTransaction
associated with this instanceStaleTransactionException
- if the transaction associated with this instance is no longer usableJTransaction getTransaction()
JTransaction
.JTransaction
that contains this instance's field statedefault boolean delete()
See Transaction.delete()
for details on secondary deletions from
DeleteAction.DELETE
and JField.cascadeDelete()
.
StaleTransactionException
- if the transaction associated with the current thread is no longer usableReferencedObjectException
- if the object is referenced by some other object
through a reference field configured for DeleteAction.EXCEPTION
default boolean exists()
StaleTransactionException
- if the transaction associated with this instance is no longer usabledefault boolean isSnapshot()
SnapshotJTransaction
.
Equivalent to getTransaction().isSnapshot()
.
default boolean recreate()
StaleTransactionException
- if the transaction associated with this instance is no longer usabledefault void revalidate(Class<?>... groups)
The actual validation will occur either during JTransaction.commit()
or at the next invocation of JTransaction.validate()
, whichever occurs first.
The specified validation groups, if any, will be used.
If the associated transaction was opened with ValidationMode.DISABLED
, no validation will be performed.
groups
- validation group(s) to use for validation; if empty, Default
is assumedDeletedObjectException
- if this object does not exist in the JTransaction
associated with this instanceIllegalStateException
- if transaction commit is already in progressStaleTransactionException
- if the transaction associated with this instance is no longer usableNullPointerException
- if groups
is nulldefault boolean upgrade()
If a version change occurs, matching @OnVersionChange
methods will be invoked prior to this method returning.
DeletedObjectException
- if this object does not exist in the JTransaction
associated with this instanceStaleTransactionException
- if the transaction associated with this instance is no longer usabledefault JObject copyTo(JTransaction dest, CopyState copyState, String... refPaths)
This is a more general method; see copyIn()
and copyOut()
for more common and specific use cases.
This method copies this object and all other objects reachable from this instance through any of the specified reference paths (including intermediate objects visited).
This instance will first be upgrade()
ed if necessary. If any copied object already exists in dest
,
it will have its schema version updated first, if necessary, then be overwritten.
Any @OnVersionChange
, @OnCreate
,
and @OnChange
methods will be notified accordingly as usual (in dest
);
however, for @OnCreate
and
@OnChange
, the annotation must have snapshotTransactions = true
if dest
is a SnapshotJTransaction
.
The two transactions must be compatible in that for any schema versions encountered, those schema versions must be identical in both transactions.
Circular references are handled properly: if an object is encountered more than once, it is not copied again.
The copyState
tracks which objects have already been copied and/or traversed along some reference path.
For a "fresh" copy operation, pass a newly created CopyState
; for a copy operation that is a continuation
of a previous copy, reuse the previous copyState
. The CopyState
may also be configured to remap object ID's.
Warning: if two threads attempt to copy objects between the same two transactions at the same time but in opposite directions, deadlock could result.
dest
- destination transaction for copiescopyState
- tracks which indirectly referenced objects have already been copiedrefPaths
- zero or more reference paths that refer to additional objects to be copieddest
DeletedObjectException
- if this object does not exist in the JTransaction
associated with this instance
(no exception is thrown however if an indirectly referenced object does not exist unless it is traversed)DeletedObjectException
- if any object to be copied does not actually existDeletedObjectException
- if any copied object ends up with a reference to an object
that does not exist in dest
through a reference field configured to disallow deleted assignmentSchemaMismatchException
- if the schema corresponding to any copied object is not identical in both the JTransaction
associated with this instance and dest
IllegalArgumentException
- if any parameter is nullIllegalArgumentException
- if any path in refPaths
is invalidcopyIn()
,
copyOut()
,
JTransaction.copyTo()
,
ReferencePath
default JObject copyOut(String... refPaths)
Normally this method would only be invoked on a regular database JObject
.
The returned object will always be a snapshot JObject
.
This is a convenience method, and is equivalent to invoking:
this.copyTo(this.getTransaction().getSnapshotTransaction(), new CopyState(), refPaths);
refPaths
- zero or more reference paths that refer to additional objects to be copiedJObject
copy of this instanceDeletedObjectException
- if any copied object ends up with a reference to an object
that does not exist in dest
through a reference field
configured to disallow deleted assignment
in snapshot transactionsIllegalArgumentException
- if this instance is a snapshot instanceIllegalArgumentException
- if any path in refPaths
is invalidcopyIn()
default JObject copyIn(String... refPaths)
refPaths
(if any),
into the transaction associated with the current thread.
Normally this method would only be invoked on a snapshot JObject
.
The returned object will be a JObject
in the currently open transaction.
This is a convenience method, and is equivalent to invoking:
this.copyTo(JTransaction.getCurrent(), new CopyState(), refPaths)
refPaths
- zero or more reference paths that refer to additional objects to be copiedDeletedObjectException
- if any copied object ends up with a reference to an object
that does not exist in dest
through a reference field
configured to disallow deleted assignmentSchemaMismatchException
- if the schema corresponding to this object's version is not identical in both transactionsIllegalArgumentException
- if any path in refPaths
is invalidcopyOut()
default JObject cascadeCopyTo(JTransaction dest, String cascadeName, boolean clone)
This is a convenience method, and is equivalent to invoking:
this.cascadeCopyTo(dest, cascadeName, -1, clone);
dest
- destination transaction for copiescascadeName
- cascade name, or null for no cascade (i.e., copy only this instance)clone
- true to clone objects, i.e., assign the copies new, unused object ID's in dest
,
or false to preserve the same object ID's, overwriting any existing objects in dest
dest
DeletedObjectException
- if any object to be copied does not existDeletedObjectException
- if any copied object ends up with a reference to an object
that does not exist in dest
through a reference field configured to disallow deleted assignmentSchemaMismatchException
- if the schema version corresponding to any copied object is not identical in both transactionsIllegalArgumentException
- if dest
is nullcascadeCopyTo(JTransaction, String, int, boolean)
default JObject cascadeCopyTo(JTransaction dest, String cascadeName, int recursionLimit, boolean clone)
This is a more general method; see cascadeCopyIn()
and cascadeCopyOut()
for more common and specific use cases.
This method finds and copies all objects reachable from this object based on
@JField.cascades()
and
@JField.inverseCascades()
annotation properties on
reference fields: a reference field is traversed in the forward or inverse direction if cascadeName
is
specified in the corresponding annotation property. See @JField
for details.
The recursionLimit
parameter can be used to limit the maximum distance of any copied object,
measured in the number of reference field "hops" from this object.
This instance will first be upgrade()
ed if necessary. If any copied object already exists in dest
,
it will have its schema version updated first, if necessary, then be overwritten.
Any @OnVersionChange
, @OnCreate
,
and @OnChange
methods will be notified accordingly as usual (in dest
);
however, for @OnCreate
and
@OnChange
, the annotation must have snapshotTransactions = true
if dest
is a SnapshotJTransaction
.
The two transactions must be compatible in that for any schema versions encountered, those schema versions must be identical in both transactions.
Circular references are handled properly: if an object is encountered more than once, it is not copied again.
The copyState
tracks which objects have already been copied and traversed.
For a "fresh" copy operation, pass a newly created CopyState
; for a copy operation that is a continuation
of a previous copy, reuse the previous copyState
. The CopyState
may also be configured to remap object ID's.
Warning: if two threads attempt to copy objects between the same two transactions at the same time but in opposite directions, deadlock could result.
dest
- destination transaction for copiescascadeName
- cascade name, or null for no cascade (i.e., copy only this instance)recursionLimit
- the maximum number of references to hop through, or -1 for infinityclone
- true to clone objects, i.e., assign the copies new, unused object ID's in dest
,
or false to preserve the same object ID's, overwriting any existing objects in dest
dest
DeletedObjectException
- if any object to be copied does not existDeletedObjectException
- if any copied object ends up with a reference to an object
that does not exist in dest
through a reference field configured to disallow deleted assignmentSchemaMismatchException
- if the schema version corresponding to any copied object is not identical in both transactionsIllegalArgumentException
- if recursionLimit
is less that -1IllegalArgumentException
- if dest
is nullcascadeCopyIn()
,
cascadeCopyOut()
,
JTransaction.cascadeFindAll()
default JObject cascadeCopyOut(String cascadeName, boolean clone)
Normally this method would only be invoked on a regular database JObject
.
The returned object will always be a snapshot JObject
.
This is a convenience method, and is equivalent to invoking:
this.cascadeCopyTo(this.getTransaction().getSnapshotTransaction(), cascadeName, clone);
cascadeName
- cascade name, or null for no cascade (i.e., copy only this instance)clone
- true to clone objects, i.e., assign the copies new, unused object ID's in the snapshot transaction,
or false to preserve the same object ID's, overwriting any existing objectsJObject
copy of this instanceDeletedObjectException
- if any object to be copied does not existDeletedObjectException
- if any copied object ends up with a reference to an object
that does not exist in dest
through a reference field
configured to disallow deleted assignment
in snapshot transactionsSchemaMismatchException
- if the schema version corresponding to any copied object is not identical in both transactionsIllegalArgumentException
- if this instance is a snapshot instancecascadeCopyIn()
,
cascadeCopyTo()
default JObject cascadeCopyIn(String cascadeName, boolean clone)
Normally this method would only be invoked on a snapshot JObject
.
The returned object will be a JObject
in the currently open transaction.
This is a convenience method, and is equivalent to invoking:
this.cascadeCopyTo(JTransaction.getCurrent(), cascadeName, clone);
cascadeName
- cascade name, or null for no cascade (i.e., copy only this instance)clone
- true to clone objects, i.e., assign the copies new, unused object ID's in the database transaction,
or false to preserve the same object ID's, overwriting any existing objectsDeletedObjectException
- if any object to be copied does not existDeletedObjectException
- if any copied object ends up with a reference to an object
that does not exist in dest
through a reference field
configured to disallow deleted assignmentSchemaMismatchException
- if the schema version corresponding to any copied object is not identical in both transactionscascadeCopyOut()
,
cascadeCopyTo()
void resetCachedFieldValues()
JObject
s instances may cache simple field values after they have been read from the underlying
key/value store for efficiency. This method causes any such cached values to be forgotten, so they will
be re-read from the underlying key/value store on the next read of the field.
Normally this method does not need to be used. It may be needed to maintain consistency in exotic situations, for example, where the underlying key/value store is being modified directly.
default <R> NavigableSet<R> findReferring(Class<R> type, String fieldName)
The fieldName
can be the name of a simple reference field (e.g., "teacher"
)
or a sub-field of a complex field (e.g., "students.element"
).
R
- type of referring objectstype
- type of referring objectsfieldName
- name of reference fieldStaleTransactionException
- if the transaction associated with this instance is no longer openIllegalArgumentException
- if either parameter is nulldefault JClass<?> getJClass()
JClass
TypeNotInSchemaVersionException
- if this instance has a type that does not exist
in this instance's schema version, i.e., this instance is an UntypedJObject
Copyright © 2022. All rights reserved.