public class Persistence
extends java.lang.Object
An instance of this class is retrieved from PersistenceFactory.getInstance(Database)
method
One instance of this class is associated with a single, physical database. Multiple user sessions can
use this shared instance; each will have its own context.
An instance of a concrete LockManager
implementation is created
for each each instance of this class. The implementation to use is queried from the directory service,
and defaults to the InMemoryLockManager
if no other implementation is specified in the
directory.
Transactions are explicitly managed with beginTransaction()
, commit()
and rollback()
.
Only one transaction per client context may be active at a time. These are database-level transactions,
which may or may not coincide with application-level transactions.
External code which directly accesses query methods within the Persistence
class should
always properly bracket its use of these methods with transactions.
ORM sessions are managed implicitly, transparently to application code and even to other classes within
the persistence framework. No more than one session per user context may be active at a time. Sessions are
opened lazily as they are needed to fulfill database operations: executing a query, persisting a record,
creating a temporary table, etc. They are closed when the runtime environment detects that they are no
longer needed by any active resource. Upon opening a new session, the current context's BufferManager
instance is interrogated for all active records. These are the current records stored in
all open record buffers for the database matching the current Persistence
instance. They represent
detached records previously associated with the last open session (if any).
Modifier and Type | Class and Description |
---|---|
(package private) class |
Persistence.Context
A storage and work area for context-local variables used by the
enclosing class.
|
private static class |
Persistence.QueryKey
A hash key for a unique combination of FQL, with the existence of lack of maximum results,
and starting row offset options.
|
Modifier and Type | Field and Description |
---|---|
private static boolean |
active
true if the persistence layer can be used. |
private ContextLocal<Persistence.Context> |
context
Context local object to manage persistence variables
|
private Database |
database
Database served by this object
|
private static java.lang.String |
DEFAULT_IDENTITY_MANAGER
Default identity manager implementation
|
private static java.lang.String |
DEFAULT_LOCK_MANAGER
Default lock manager implementation
|
private Dialect |
dialect
Database dialect helper
|
private DmoVersioning |
dmoVersion
DMO version tracker (persistent databases only)
|
private static boolean |
foreignKeysEnabled
Flag indicating whether records are joined using foreign keys
|
private int |
hashCode
Cached hash code
|
static java.lang.String |
ID_GEN_SEQUENCE
Well-known name of ID generator sequence
|
private IdentityManager |
identityManager
Identity manager
|
private long |
listThreshold
Milliseconds a list query may take before being reported
|
private long |
loadByIDThreshold
Milliseconds a load-by-id query may take before being reported
|
private long |
loadThreshold
Milliseconds a load query may take before being reported
|
private LockManager<java.lang.String> |
lockManager
Pessimistic lock manager
|
private LockTableUpdater |
lockTableUpdater
Object which keeps lock metadata in sync with record lock activity
|
private static java.util.logging.Logger |
LOG
Logger
|
private long |
scrollThreshold
Milliseconds a scrolling query may take before being reported
|
private boolean |
temporary
Does this object represent the temporary database?
|
Modifier | Constructor and Description |
---|---|
protected |
Persistence(Database database,
Dialect dialect)
Construct an instance for a particular, physical database, storing the dialect which is used to create
a portability layer.
|
Modifier and Type | Method and Description |
---|---|
boolean |
beginTransaction()
Make sure a (new) transaction instance is created and stored in the local context.
|
(package private) boolean |
beginTransaction(Persistence.Context local,
SavepointManager savepointManager)
Begin a new transaction and store the instance in the local context.
|
(package private) boolean |
beginTransaction(SavepointManager savepointManager) |
private boolean |
checkReadOnly(java.lang.String[] entities)
Determine whether all of the given DMO entity names represent read-only tables.
|
void |
cleanup()
Clean up the current context.
|
void |
commit()
Commit the current database transaction and close the current session.
|
(package private) void |
commit(Persistence.Context local)
Commit the current database transaction and close the current session.
|
protected IdentityManager |
createIdentityManager()
Create and initialize the identity manager to be used with this
instance of persistence services for the given database.
|
protected LockManager<java.lang.String> |
createLockManager()
Create and initialize the lock manager to be used with this instance of
persistence services for the given database.
|
void |
delete(Record dmo)
Delete the persisted object from the specified database.
|
int |
deleteOrUpdate(java.lang.String fql,
java.lang.Object[] values,
java.lang.String entity,
boolean noUndo)
Perform a bulk delete or update of all objects which meet the specified
criteria.
|
(package private) void |
deregisterSessionListener(SessionListener listener)
Deregister a session listener when it no longer needs to receive session life cycle events.
|
(package private) void |
enableTransactionTrace(boolean enable)
Set enable mode for transaction tracing in the current context.
|
boolean |
equals(java.lang.Object o)
Override the parent's implementation to ensure it is consistent with
hashCode . |
(package private) void |
evict(java.util.Collection<Record> evictees)
Evict a collection of DMOs from the current ORM session.
|
(package private) void |
evict(Persistence.Context local,
Record dmo)
Evict the given DMO from the current session immediately.
|
int |
executeSQL(java.lang.String sql)
Execute an arbitrary SQL statement which does not produce a result set.
|
int |
executeSQL(java.lang.String sql,
java.lang.Object[] args)
Execute an arbitrary SQL statement which does not produce a result set.
|
(package private) int |
executeSQL(java.lang.String sql,
java.lang.Object[] args,
boolean noUndo)
Execute an arbitrary SQL statement which does not produce a result set.
|
void |
executeSQLBatch(java.util.List<java.lang.String> sql,
boolean noFlush)
Execute an arbitrary list of SQL statements in batch.
|
(package private) void |
executeSQLBatch(Persistence.Context local,
java.util.List<java.lang.String> sql,
boolean noFlush)
Execute an arbitrary list of standard JDBC statements in batch.
|
(package private) void |
executeSQLBatch(java.lang.String sql,
java.util.function.Supplier<java.lang.Object[]> getArgs)
Execute a batch SQL statement, while the argument supplier returns non-null values.
|
<T> ScrollableResults<T> |
executeSQLQuery(java.lang.String sql,
java.lang.Object[] args)
Execute an arbitrary SQL query.
|
void |
flush()
Flush the current session, which synchronizes the in-memory state of
DMOs to the database.
|
private void |
flush(boolean clear)
Flush the current session, which synchronizes the in-memory state of
DMOs to the database.
|
private void |
flush(Persistence.Context local,
Session session,
boolean clear)
Flush the current session, which synchronizes the in-memory state of
DMOs to the database.
|
static Persistence |
get(java.lang.String name)
Deprecated.
Use
PersistenceFactory.getInstance(String) instead. |
(package private) java.lang.Throwable |
getBeginTxTrace()
Retrieve trace information about where the current transaction, if any, was started.
|
(package private) Persistence.Context |
getContext()
Get the context for the current user session.
|
Database |
getDatabase()
Get the database information object associated with this persistence
service object.
|
Dialect |
getDialect()
Get the database dialect helper object associated with the database
backing this object.
|
IdentityManager |
getIdentityManager()
Get the identity manager associated with this
Persistence
instance. |
LockManager<java.lang.String> |
getLockManager()
Get the lock manager associated with this
Persistence
instance. |
private Query |
getQuery(Persistence.Context local,
java.lang.String fql,
int maxResults,
int startOffset,
java.lang.Object[] values,
boolean readOnly)
Get or create a query for the given FQL query string.
|
RecordLockContext |
getRecordLockContext()
Get the record lock context associated with the current client session.
|
Session |
getSession()
Get the ORM session associated with the current context, creating one if needed.
|
<T> T |
getSingleSQLResult(java.lang.String sql,
java.lang.Object[] args)
Convenience method to retrieve a single result from a SQL statement.
|
private void |
handleException(java.lang.String message,
PersistenceException exc)
Raise a STOP condition, if the given exception represents a catastrophic, JDBC failure;
else throw a
PersistenceException . |
int |
hashCode()
Override the parent's implementation to return a hash code cached at construction.
|
static void |
initialize()
Initialize various infrastructure components of the persistence framework:
DataTypeHelper , which is used when preprocessing FQL where clauses. |
protected void |
initializeInstance()
Initialize the helper objects to which this object delegates certain service requests.
|
static boolean |
isActive()
Reports if the persistence layer can be used or not.
|
(package private) static boolean |
isForeignKeysEnabled()
Determine whether records are joined using foreign keys.
|
(package private) boolean |
isTemporary()
Determine whether this persistence object is for a temporary table database.
|
boolean |
isTransactionOpen()
Indicate whether an explicit, database-level transaction currently is open.
|
<T> java.util.List<T> |
list(java.lang.String[] entities,
java.lang.String fql,
java.lang.Object[] values,
int maxResults,
int startOffset,
boolean readOnlyQuery,
boolean noFlush)
Execute an FQL query and return the results as a list.
|
<T> java.util.List<T> |
list(java.lang.String fql,
java.lang.Object[] values,
int maxResults,
int startOffset,
boolean readOnlyQuery)
Execute an FQL query and return the results as a list.
|
Record |
load(java.lang.Class<? extends Record> implClass,
java.lang.Long id,
LockType lockType,
long timeout,
boolean updateLock)
Load a single record from the session-level cache or, optionally, refresh it from the
database.
|
Record |
load(RecordBuffer buffer,
java.lang.String fql,
java.lang.Object[] values,
LockType lockType,
long timeout,
boolean unique,
boolean updateLock,
boolean forceRefresh,
boolean findByKey)
Execute an FQL query and load a single record from the session-level cache or, optionally,
refresh it from the database.
|
void |
lock(LockType lockType,
RecordIdentifier<java.lang.String> ident,
boolean update)
Attempt to obtain the specified lock type on a particular record.
|
void |
lock(LockType lockType,
RecordIdentifier<java.lang.String> ident,
boolean update,
long timeout)
Attempt to obtain the specified lock type on a particular record.
|
LockType |
lockTable(java.lang.String table,
LockType lockType,
boolean update)
Attempt to obtain the specified lock type on a table.
|
Record |
merge(Record dmo)
Deprecated.
|
java.lang.String |
message(java.lang.String message)
Format the given message text by prepending a descriptor including the
user's current context and the physical name of the database.
|
java.lang.Long |
nextPrimaryKey(java.lang.String table)
Obtain the next available primary key ID on a per-table basis.
|
static java.lang.Object |
preprocessQueryParameter(java.lang.Object arg,
Dialect dialect)
Perform special handling on a query substitution parameter to avoid
errors during query execution.
|
private void |
preprocessQueryParameters(java.lang.Object[] args)
Perform special handling on query substitution parameters to avoid
errors during query execution.
|
LockType |
queryLock(RecordIdentifier<java.lang.String> ident)
Query the lock type currently held by the current context for the
specified database record.
|
Record |
quickLoad(RecordIdentifier<java.lang.String> ident)
Load a single record from the database or from the session-level cache.
|
Record |
quickLoad(RecordIdentifier<java.lang.String> ident,
boolean refresh)
Load a single record from the database or from the session-level cache.
|
(package private) void |
registerSessionListener(SessionListener listener,
SessionListener.Scope scope)
Register a
SessionListener to receive session life
cycle event notifications. |
(package private) void |
reportUDFVersion(Database database)
Logs the FWD version returned by the getFWDVersion user-defined function (UDF/p2jpl) for
this database.
|
void |
rollback()
Roll back the current database transaction and close the current
session.
|
(package private) void |
rollback(Persistence.Context local)
Roll back the current database transaction and close the current
session.
|
void |
save(Record dmo,
java.lang.Long id)
Persist the specified object to the backing database session, using the given ID.
|
(package private) void |
save(Record dmo,
java.lang.Long id,
boolean updateDmoState)
Persist the specified object to the backing database session, using the given ID.
|
<T> ScrollableResults<T> |
scroll(java.lang.String[] entities,
java.lang.String fql,
java.lang.Object[] values,
int maxResults,
int startOffset,
int scrollMode)
Execute an FQL query and get a scrollable cursor on the result set.
|
<T> ScrollableResults<T> |
scroll(java.lang.String fql,
java.lang.Object[] values)
Execute an FQL query and get a scrollable cursor on the result set.
|
<T> ScrollableResults<T> |
scroll(java.lang.String fql,
java.lang.Object[] values,
int maxResults,
int startOffset)
Execute an FQL query and get a scrollable cursor on the result set.
|
<T> ScrollableResults<T> |
scroll(java.lang.String fql,
java.lang.Object[] values,
int maxResults,
int startOffset,
int scrollMode)
Execute an FQL query and get a scrollable cursor on the result set.
|
(package private) void |
shareLockTableUpdater(Database database)
If this object is associated with a metadata database, set this object's lock table updater
to be the same as that of the
Persistence instance associated with the given,
primary database. |
(package private) void |
uniqueResultViolation(RecordBuffer buffer,
java.lang.Exception exc)
Process an error condition in which a unique result should have been
found, but multiple results occurred.
|
public static final java.lang.String ID_GEN_SEQUENCE
private static final java.util.logging.Logger LOG
private static final java.lang.String DEFAULT_LOCK_MANAGER
private static final java.lang.String DEFAULT_IDENTITY_MANAGER
private static boolean foreignKeysEnabled
private static volatile boolean active
true
if the persistence layer can be used.private final ContextLocal<Persistence.Context> context
private final Database database
private final Dialect dialect
private final boolean temporary
private final int hashCode
private final long scrollThreshold
private final long listThreshold
private final long loadThreshold
private final long loadByIDThreshold
private final DmoVersioning dmoVersion
private LockManager<java.lang.String> lockManager
private LockTableUpdater lockTableUpdater
private IdentityManager identityManager
protected Persistence(Database database, Dialect dialect)
database
- Database with which this instance is permanently associated.dialect
- Portability object used to issue dialect-specific commands to the database.public static Persistence get(java.lang.String name)
PersistenceFactory.getInstance(String)
instead.name
- Name of physical database with which the instance is
permanently associated.public static void initialize() throws PersistenceException
DataTypeHelper
, which is used when preprocessing FQL where clauses.
BufferManager
, which tracks open buffers and transactions.
ChangeBroker
, which dispatches notifications about changes to DMO properties.
DatabaseManager
, which configures the ORM environment for the databases
to which the framework connects.
P2OLookup
, instances of which are used for runtime, on-the-fly query and
temp-table conversion.
DatabaseTriggerManager
, which tracks and fires database triggers at the
appropriate times.
java.lang.IllegalStateException
- if invoked more than once.PersistenceException
- if any error is encountered initializing the persistence framework.DataTypeHelper.initialize()
,
BufferManager.initialize()
,
ChangeBroker.initialize()
,
DatabaseManager.initialize()
,
TemporaryDatabaseManager.initialize()
,
DataSetManager.initialize()
,
P2OLookup.initialize()
public static boolean isActive()
true
if the persistence layer is initialized and can be used.public static java.lang.Object preprocessQueryParameter(java.lang.Object arg, Dialect dialect)
character
. Any
parameter affected is replaced with a new character
instance at the same index position within args
.
date
instance at the same index position within args
.
Note: this method has special processing for null
bytes
embedded in character
variables. The text of the variable
is truncated starting at the first embedded null
byte.
This means that the resulting substitution parameters are guaranteed
to never include null
bytes.
arg
- A single substitution parameter.dialect
- Database dialect.static boolean isForeignKeysEnabled()
true
if records are joined using foreign keys;
false
if records are joined using legacy key
fields.void reportUDFVersion(Database database) throws PersistenceException
PersistenceException
- if there is a problem creating a database session or statement.public final int hashCode()
hashCode
in class java.lang.Object
public final boolean equals(java.lang.Object o)
hashCode
.equals
in class java.lang.Object
public Dialect getDialect()
public Database getDatabase()
public LockManager<java.lang.String> getLockManager()
Persistence
instance. For temp tables, this will be null
, since temp
table data is naturally compartmentalized and record locking is
meaningless in this case. For permanent databases, this method will
return the lock manager created when this class was instantiated.public IdentityManager getIdentityManager()
Persistence
instance. For temp tables, this will be null
, since for
temp tables unique primary keys generated using TemporaryBuffer.nextPrimaryKey()
. For permanent databases, this
method will return the identity manager created when this class was
instantiated.public <T> ScrollableResults<T> scroll(java.lang.String fql, java.lang.Object[] values) throws PersistenceException
Note:
While this method attempts to use a server-side database cursor to fetch results, some JDBC
driver implementations (e.g., PostgreSQL) may store an intermediate form of the
entire result set in memory instead, effectively doubling the amount of memory
required. To avoid this, consider using scroll(String, Object[], int, int, int)
instead. Using that method with a ScrollMode
of FORWARD_ONLY
and setting a
JDBC fetch size to a reasonable value may allow a JDBC driver to use a server-side cursor to
fetch smaller batches of results at a time. Consult your JDBC driver documentation and/or
source code to determine whether this is an issue for your JDBC implementation.
fql
- FQL query statement.values
- Substitution values for the query. If none, this should be an empty array.PersistenceException
- if there was an error executing the query.public <T> ScrollableResults<T> scroll(java.lang.String fql, java.lang.Object[] values, int maxResults, int startOffset) throws PersistenceException
Note:
While this method attempts to use a server-side database cursor to fetch results, some JDBC
driver implementations (e.g., PostgreSQL) may store an intermediate form of the
entire result set in memory instead, effectively doubling the amount of memory
required. To avoid this, consider using scroll(String, Object[], int, int, int)
instead. Using that method with a ScrollMode
of FORWARD_ONLY
and setting a
JDBC fetch size to a reasonable value may allow a JDBC driver to use a server-side cursor to
fetch smaller batches of results at a time. Consult your JDBC driver documentation and/or
source code to determine whether this is an issue for your JDBC implementation.
fql
- FQL query statement.values
- Substitution values for the query. If none, this should be an empty array.maxResults
- The maximum number of elements to be returned in the list.
If this value is non-positive, no upper limit is applied.startOffset
- The 0-based offset of the first record to retrieve. If this
value is non-positive, an offset of 0 is used by default.PersistenceException
- if there was an error executing the query.public <T> ScrollableResults<T> scroll(java.lang.String fql, java.lang.Object[] values, int maxResults, int startOffset, int scrollMode) throws PersistenceException
fql
- FQL query statement.values
- Substitution values for the query. If none, this should be an
empty array.maxResults
- The maximum number of elements to be returned in the list.
If this value is non-positive, no upper limit is applied.startOffset
- The 0-based offset of the first record to retrieve. If this
value is non-positive, an offset of 0 is used by default.scrollMode
- Scroll mode which should apply to the result set.PersistenceException
- if there was an error executing the query.public <T> ScrollableResults<T> scroll(java.lang.String[] entities, java.lang.String fql, java.lang.Object[] values, int maxResults, int startOffset, int scrollMode) throws PersistenceException
entities
- Names of the DMO entities associated with this query statement.fql
- FQL query statement to be parsed and executed by ORM framework.values
- Substitution values for the query. If none, this should be an empty array.maxResults
- The maximum number of elements to be returned in the list. If this value is non-positive, no
upper limit is applied.startOffset
- The 0-based offset of the first record to retrieve. If this value is non-positive, an offset
of 0 is used by default.scrollMode
- Scroll mode which should apply to the result set.PersistenceException
- if there was an error executing the query.public <T> java.util.List<T> list(java.lang.String fql, java.lang.Object[] values, int maxResults, int startOffset, boolean readOnlyQuery) throws PersistenceException
Object
s.
No locking is attempted.
Note:
This method should be used only for queries that are expected to return a relatively small
result set, since the entire result set is stored in the returned list. Additionally, some
JDBC driver implementations (e.g., PostgreSQL) may store an intermediate form of the result
set in memory, effectively doubling the amount of memory required. To avoid this, consider
using scroll(String, Object[], int, int, int)
instead. Using that method with a
ScrollMode
of FORWARD_ONLY
and setting a JDBC fetch size to a reasonable
value may allow a JDBC driver to use a server-side cursor to fetch smaller batches of
results at a time. Consult your JDBC driver documentation and/or source code to determine
whether this is an issue for your JDBC implementation.
fql
- FQL query statement.values
- Substitution values for the query. If none, this should be an empty array.maxResults
- The maximum number of elements to be returned in the list.
If this value is non-positive, no upper limit is applied.startOffset
- The 0-based offset of the first record to retrieve. If this
value is non-positive, an offset of 0 is used by default.readOnlyQuery
- true
to execute the query in read-only mode, else false
.null
if no result was found.PersistenceException
- if there was an error executing the query.public <T> java.util.List<T> list(java.lang.String[] entities, java.lang.String fql, java.lang.Object[] values, int maxResults, int startOffset, boolean readOnlyQuery, boolean noFlush) throws PersistenceException
Object
s.
No locking is attempted.
Note:
This method should be used only for queries that are expected to return a relatively small
result set, since the entire result set is stored in the returned list. Additionally, some
JDBC driver implementations (e.g., PostgreSQL) may store an intermediate form of the result
set in memory, effectively doubling the amount of memory required. To avoid this, consider
using scroll(String, Object[], int, int, int)
instead. Using that method with a
ScrollMode
of FORWARD_ONLY
and setting a JDBC fetch size to a reasonable
value may allow a JDBC driver to use a server-side cursor to fetch smaller batches of
results at a time. Consult your JDBC driver documentation and/or source code to determine
whether this is an issue for your JDBC implementation.
T
- Type of object being listed.entities
- Names of the DMO entities associated with this query statement.fql
- FQL query statement to be processed. This method makes no assumptions as to the
types of object(s) returned.values
- Substitution values for the query. If none, this should be an empty array.maxResults
- The maximum number of elements to be returned in the list. If this value is
non-positive, no upper limit is applied.startOffset
- The 0-based offset of the first record to retrieve. If this value is non-positive,
an offset of 0 is used by default.readOnlyQuery
- true
to execute the query in read-only mode, else false
.noFlush
- No longer used. Should be removed.null
if no result was found.PersistenceException
- if there was an error executing the query.public Record load(RecordBuffer buffer, java.lang.String fql, java.lang.Object[] values, LockType lockType, long timeout, boolean unique, boolean updateLock, boolean forceRefresh, boolean findByKey) throws PersistenceException
buffer
argument is used only to extract information needed
to perform the query.buffer
- Record buffer which holds information about the DMO class type
and name of the table being queried.fql
- FQL query statement. This may be either an ID-only projection query or a full query
(see above).values
- Substitution values for the query. If none, this should be an empty array.lockType
- Type of lock the lock manager should register on the resulting
record for the current user context.timeout
- Number of milliseconds to wait to acquire the requested lock type.
Throws LockTimeoutException
if this time elapses before the
lock is acquired. Specify 0 to wait indefinitely for the lock. Ignored
if lockType
is NONE
.unique
- true
if no more than one result is expected from this query;
false
if the query could result in more than one record.updateLock
- true
to update the current lock state;
false
to leave the current lock state unchanged.forceRefresh
- If true
forces the record to be refreshed from database. Otherwise
it will be refreshed only if the lockType has been upgraded from NONE.findByKey
- If true
, this overrides the current rereadnolock
setting;
if false
, honor rereadnolock
.null
if no result
was found.LockTimeoutException
- if a record was found, but its lock could not be acquired within the positive
timeout
period specified.LockUnavailableException
- if a record was found and a no-wait lock type was specified, but the lock could
not be acquired immediately.PersistenceException
- if there was an error executing the query or if a unique query
(i.e., unique == true
) returned multiple results,public Record load(java.lang.Class<? extends Record> implClass, java.lang.Long id, LockType lockType, long timeout, boolean updateLock) throws PersistenceException, LockTimeoutException
implClass
- The DMO implementation class of record being read.id
- Primary key of the record to be loaded into the buffer. May not be null
.lockType
- Type of lock the lock manager should register on the resulting record for the
current user context.timeout
- Number of milliseconds to wait to acquire the requested lock type. Throws
LockTimeoutException
if this time elapses before the lock is acquired.
Specify 0 to wait indefinitely for the lock. Ignored if lockType
is
NONE
.updateLock
- true
to update the current lock state;
false
to leave the current lock state unchanged.null
if no result was
found.LockTimeoutException
- if a record was found, but its lock could not be acquired within the positive
timeout
period specified.LockUnavailableException
- if a record was found and a no-wait lock type was specified, but the lock could
not be acquired immediately.PersistenceException
- if there was an error loading the DMO from the ORM session and/or database.public Record quickLoad(RecordIdentifier<java.lang.String> ident) throws PersistenceException
ident
- Record identifier of the record to be loaded. Consists of the
primary key and the fully qualified DMO entity name.null
if no result was found.PersistenceException
- if there was an error creating an ORM session or getting the requested record.public Record quickLoad(RecordIdentifier<java.lang.String> ident, boolean refresh) throws PersistenceException
ident
- Record identifier of the record to be loaded. Consists of the
primary key and the fully qualified DMO entity name.refresh
- If true
then re-read the state of the record from
the underlying database. This is useful when record has been
changed bypassing the FWD ORM.null
if no result was found.PersistenceException
- if there was an error creating an ORM session or getting the requested record.public int executeSQL(java.lang.String sql) throws PersistenceException
FastFindCache
) of each buffer affected by
this statement. This cannot be done here because the method is not aware of the buffer list and if
multiple SQL statements are batch executed, then is better to issue a single invalidate command for all
of then.sql
- SQL statement text.-1
if the statement
did not complete normally.PersistenceException
- if any error occurs executing the statement.public int executeSQL(java.lang.String sql, java.lang.Object[] args) throws PersistenceException
FastFindCache
) of each buffer affected by
this statement. This cannot be done here because the method is not aware of the buffer list and if
multiple SQL statements are batch executed, then is better to issue a single invalidate command for all
of then.sql
- SQL statement text.args
- The statement arguments.-1
if the statement
did not complete normally.PersistenceException
- if any error occurs executing the statement.public <T> ScrollableResults<T> executeSQLQuery(java.lang.String sql, java.lang.Object[] args) throws PersistenceException
It is the responsibility of the calling code to close the returned result set. In addition, if this
method is called outside of a database transaction, the caller should optionally invoke
beginTransaction()
before calling this method and commit()
or
rollback()
after fully processing the result set returned by this method. This will
ensure a transaction is opened and properly closed if necessary.
sql
- SQL query text.args
- The query parameters.PersistenceException
- if any error occurs executing the statement.public <T> T getSingleSQLResult(java.lang.String sql, java.lang.Object[] args) throws PersistenceException
The result set and statement are closed immediately; no additional cleanup is required by the caller.
Note that, if this method is called outside of a database transaction, the caller should optionally
invoke beginTransaction()
before calling this method and
commit()
or rollback()
after fully processing the result set
returned by this method. This will ensure a transaction is opened and properly closed if necessary.
sql
- SQL statement to execute.args
- Query substitution parameters, if any. If present, these should match the number
of placeholders in the SQL statement. If not present, this argument may either be
null
or an empty array.PersistenceException
- if any error occurs, either during the statement's execution, or when pushing or
popping an implicit transaction.public void executeSQLBatch(java.util.List<java.lang.String> sql, boolean noFlush) throws PersistenceException
sql
- List of SQL statements to execute in batch.noFlush
- If true
, flushing is bypassed.PersistenceException
- if any error occurs executing the statements.public void lock(LockType lockType, RecordIdentifier<java.lang.String> ident, boolean update) throws LockUnavailableException
In the no-wait case, an exception is raised indicating that the lock is not available.
The current thread continues normally once the lock is obtained.
A lock currently held can be released by specifying LockType.NONE
for the
lockType
parameter.
The normal return of this method indicates that the lock request (or lack thereof) completed successfully, and that the current context now holds a lock of the requested type.
NOTE: legacy persistence framework code should access this method only via a RecordLockContext
method, unless simply testing whether a lock is available (i.e.,
update == false
). This ensures that record locks shared across record buffers
within a client context are managed properly. Non-legacy code may access this API
directly.
lockType
- Type of lock to be obtained. LockType.NONE
is used to release an existing
lock, and to continue with no lock.ident
- ID which uniquely identifies the record being locked.update
- true
if the lock state for the current record should be updated;
else false
.LockUnavailableException
- if a "no-wait" lock cannot be acquired immediately.getRecordLockContext()
public void lock(LockType lockType, RecordIdentifier<java.lang.String> ident, boolean update, long timeout) throws LockUnavailableException
In the no-wait case, an exception is raised indicating that the lock is not available. In the timeout case, an exception is raised indicating that the timeout period elapsed.
The current thread continues normally once the lock is obtained.
A lock currently held can be released by specifying LockType.NONE
for the
lockType
parameter.
The normal return of this method indicates that the lock request (or lack thereof) completed successfully, and that the current context now holds a lock of the requested type.
NOTE: legacy persistence framework code should access this method only via a RecordLockContext
method, unless simply testing whether a lock is available (i.e.,
update == false
). This ensures that record locks shared across record buffers
within a client context are managed properly. Non-legacy code may access this API
directly.
lockType
- Type of lock to be obtained. LockType.NONE
is used to release an existing
lock, and to continue with no lock.ident
- ID which uniquely identifies the record being locked.update
- true
if the lock state for the current record should be updated;
else false
.timeout
- Number of milliseconds to wait to acquire the requested lock type.
Throws LockTimeoutException
if this time elapses before the
lock is acquired. Specify 0 to wait indefinitely for the lock. Ignored
if lockType
is NONE
.LockTimeoutException
- if a lock cannot be acquired within the positive timeout
period specified.LockUnavailableException
- if a "no-wait" lock cannot be acquired immediately.getRecordLockContext()
public LockType lockTable(java.lang.String table, LockType lockType, boolean update) throws LockUnavailableException
A lock currently held can be released by specifying
LockType.NONE
for the lockType
parameter.
Method returns previous lock type (so that calling code knows what to set it back to after bulk delete). The normal return of this method indicates that the lock request (or lack thereof) completed successfully, and that the current context now holds a lock of the requested type.
table
- Table name.lockType
- Type of lock to be obtained. LockType.NONE
is used to release an
existing lock, and to continue with no lock.update
- true
if the lock state for the current table should be updated;
else false
.LockUnavailableException
- if a "no-wait" lock cannot be acquired immediately.public LockType queryLock(RecordIdentifier<java.lang.String> ident)
This method will always return the non-NO_WAIT
variants of a lock type. That is, even if the actual lock type is
LockType.EXCLUSIVE_NO_WAIT
or
LockType.SHARE_NO_WAIT
, the simpler types of
LockType.EXCLUSIVE
and LockType.SHARE
,
respectively, are returned. The lack of a lock returns
LockType.NONE
rather than null
.
ident
- ID which uniquely identifies the record being queried.null
.public java.lang.Long nextPrimaryKey(java.lang.String table) throws PersistenceException
table
- Table for which next primary key will be returned.PersistenceException
- if there is an error determining the next primary key ID.java.lang.IllegalStateException
- if identity manager was not initialized.public void save(Record dmo, java.lang.Long id) throws PersistenceException
dmo
- DMO to be persisted.id
- Primary key to associate with the persisted DMO.PersistenceException
- if a problem occurs saving the object in the current session.void save(Record dmo, java.lang.Long id, boolean updateDmoState) throws PersistenceException
dmo
- DMO to be persisted.id
- Primary key to associate with the persisted DMO.updateDmoState
- true
to update the record state of the DMO. Should be false
for non-legacy
use cases).PersistenceException
- if a problem occurs saving the object in the current session.public Record merge(Record dmo) throws PersistenceException
dmo
- DMO to merge.PersistenceException
- in errorpublic Session getSession()
public void cleanup()
public void delete(Record dmo) throws PersistenceException
dmo
- Persistent entity to be deleted.PersistenceException
- if a problem occurs deleting the object.public int deleteOrUpdate(java.lang.String fql, java.lang.Object[] values, java.lang.String entity, boolean noUndo) throws PersistenceException
This action must take place within a database transaction, so this method attempts to begin one and commit it, if one is not already active.
This method should only be used for temp-tables (where an exclusive lock is irrelevant) or in cases where the current context already holds locks on all records which meet the specified criteria.
fql
- Query string which defines the criteria which determine which records are deleted
or updated.values
- Query substitution parameters, if any.entity
- Entity associated with the FQL statement, if any. Used to check whether a session
flush is needed before execution.noUndo
- true
if this operation is being performed on a NO-UNDO temp-table, else
false
.PersistenceException
- if a problem occurs performing the bulk delete or update.public boolean beginTransaction() throws PersistenceException
true
if a new transaction was begun;
false
if there was already an active transaction.PersistenceException
- if there is an error beginning the new transaction.public void commit() throws PersistenceException
java.lang.IllegalStateException
- if no transaction is active in the current session; this
represents a programming error.PersistenceException
- if there is an error committing the transaction.public void rollback() throws PersistenceException
java.lang.IllegalStateException
- if no transaction is active in the current session; this
represents a programming error.PersistenceException
- if there is an error rolling back the transaction.public void flush() throws PersistenceException
This request bypasses the current client context's setting as to whether flushing is enabled.
It is expected that this method will only be called within an active transaction. If no session is active, this method will raise an exception.
java.lang.IllegalStateException
- if no session currently is active.PersistenceException
- if an error occurs during session flush.public boolean isTransactionOpen()
true
if open, else false
.public java.lang.String message(java.lang.String message)
message
- Core messagepublic RecordLockContext getRecordLockContext()
persist
package and its sub-packages.protected void initializeInstance()
protected LockManager<java.lang.String> createLockManager() throws java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.ClassNotFoundException
InMemoryLockManager
.java.lang.IllegalAccessException
- if the LockManager
concrete implementation's default constructor
cannot be accessed.java.lang.InstantiationException
- if the LockManager
concrete implementation cannot be instantiated.java.lang.ClassNotFoundException
- if the LockManager
concrete implementation class cannot be located.java.lang.IllegalArgumentException
- if lock metadata is used by the current application, but no lock table updater is
found for the current database.protected IdentityManager createIdentityManager() throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException
DEFAULT_IDENTITY_MANAGER
.null
if given
database is temporary.java.lang.IllegalAccessException
- if the IdentityManager
concrete implementation's
default constructor cannot be accessed.java.lang.InstantiationException
- if the IdentityManager
concrete implementation
cannot be instantiated.java.lang.ClassNotFoundException
- if the IdentityManager
concrete implementation
class cannot be located.boolean isTemporary()
true
if temporary, else false
.boolean beginTransaction(SavepointManager savepointManager) throws PersistenceException
PersistenceException
boolean beginTransaction(Persistence.Context local, SavepointManager savepointManager) throws PersistenceException
local
- User context.true
if a new transaction was begun;
false
if there was already an active transaction.PersistenceException
- if there is an error beginning the new transaction.void commit(Persistence.Context local) throws PersistenceException
local
- User context.java.lang.IllegalStateException
- if no transaction is active in the current session; this
represents a programming error.PersistenceException
- if there is an error committing the transaction.void rollback(Persistence.Context local) throws PersistenceException
local
- User context.java.lang.IllegalStateException
- if no transaction is active in the current session; this
represents a programming error.PersistenceException
- if there is an error rolling back the transaction.void executeSQLBatch(java.lang.String sql, java.util.function.Supplier<java.lang.Object[]> getArgs) throws PersistenceException
sql
- The SQL statement to execute.getArgs
- The argument supplier.PersistenceException
void executeSQLBatch(Persistence.Context local, java.util.List<java.lang.String> sql, boolean noFlush) throws PersistenceException
local
- Persistence context.sql
- List of SQL statements to execute in batch.noFlush
- If true
, flushing is bypassed.PersistenceException
- if any error occurs executing the statements.int executeSQL(java.lang.String sql, java.lang.Object[] args, boolean noUndo) throws PersistenceException
sql
- SQL statement text.args
- The statement arguments.noUndo
- If true
, the update is on a NO-UNDO temp-table.-1
if the statement
did not complete normally.PersistenceException
- if any error occurs executing the statement.void enableTransactionTrace(boolean enable)
enable
- true
to enable; false
to disable.java.lang.Throwable getBeginTxTrace()
enableTransactionTrace(boolean)
, or this method
always will return null
.Throwable
containing stack trace from last transaction start, or
null
.void shareLockTableUpdater(Database database) throws PersistenceException
Persistence
instance associated with the given,
primary database.database
- Primary database presumably associated with the metadata database represented by
this object.PersistenceException
- if this object is not associated with a metadata database or the given database is
not a primary database.Persistence.Context getContext()
NOTE: this method is package private and should remain so. It is meant to allow optimized calls to certain frequently used methods of this class, in order to avoid the overhead of an unnecessary context local lookup.
void evict(Persistence.Context local, Record dmo)
local
- Persistence context.dmo
- Data model object to be evicted.void evict(java.util.Collection<Record> evictees)
evictees
- Collection of DMOs to be evicted.void registerSessionListener(SessionListener listener, SessionListener.Scope scope)
SessionListener
to receive session life
cycle event notifications. The listener will be deregistered
according to the following rules at the earlier of:
scope
parameter:
ENCLOSING_EXTERNAL_SCOPE
CURRENT_SCOPE
NEXT_EXTERNAL_SCOPE
listener
- Session listener to be registered.scope
- SessionListener.Scope
enum indicating the scope to
which this listener should be registered. When the scope ends,
the listener is deregistered as described above.void deregisterSessionListener(SessionListener listener)
listener
- Listener to deregister.void uniqueResultViolation(RecordBuffer buffer, java.lang.Exception exc) throws PersistenceException
buffer
- Record buffer associated with the failed query.exc
- Optional root cause exception.PersistenceException
- always; indicates the nature of the error.private void flush(boolean clear) throws PersistenceException
It is expected that this method will only be called within an active transaction. If no session is active, this method will raise an exception.
clear
- true
to clear the session (used during bulk
inserts or updates to prevent a progressive memory leak) after
the flush.PersistenceException
- if no session currently is active or if an error occurs during
session flush.private void flush(Persistence.Context local, Session session, boolean clear) throws PersistenceException
local
- Context-local state.session
- ORM sessionclear
- true
to clear the session (used during bulk
inserts or updates to prevent a progressive memory leak) after
the flush.PersistenceException
- if an error occurs during session flush.private void preprocessQueryParameters(java.lang.Object[] args)
character
. Any
parameter affected is replaced with a new character
instance at the same index position within args
.
date
instance at the same index position within args
.
Note: this method has special processing for null
bytes
embedded in character
variables. The text of the variable
is truncated starting at the first embedded null
byte.
This means that the resulting substitution parameters are guaranteed
to never include null
bytes.
args
- Array of query substitution parameters or null
if
none.private boolean checkReadOnly(java.lang.String[] entities)
entities
- DMO entity names to check, or null
.false
if entities
is null
or if any entity represents a
non-read-only table, else true
.private Query getQuery(Persistence.Context local, java.lang.String fql, int maxResults, int startOffset, java.lang.Object[] values, boolean readOnly) throws PersistenceException
local
- Context-local state.fql
- FQL query string.maxResults
- The maximum number of results to be returned by the query. If this value is
non-positive, no upper limit is applied.startOffset
- The 0-based offset of the first record to retrieve. If this value is non-positive,
an offset of 0 is used by default.values
- Substitution values for the query. If none, this should be an empty array.readOnly
- true
to prepare the query in read-only mode, else false
.PersistenceException
- if there was an error creating an ORM session.private void handleException(java.lang.String message, PersistenceException exc) throws PersistenceException
PersistenceException
.message
- Error text for the exception.exc
- A persistence exception which may or may not represent an unrecoverable database error.StopConditionException
- if the error is unrecoverable.PersistenceException
- if the error is likely recoverable.