public class DefaultDirtyShareManager extends java.lang.Object implements DirtyShareManager
DirtyShareManager
, to be used for local,
primary databases (database instances for which the current P2J server is
authoritative). Stores and shares knowledge of uncommitted modifications
to database records, specifically, those modifications which affect
database indexes.
Information about uncommitted inserts and updates to existing records is managed at two levels. A modified copy of the inserted or updated record is stored in a backing, "dirty" database. In addition, a set of in-memory data structures maintains information about the tables (or more accurately, the DMO entity names) and primary keys of affected records. The former allows the detailed, uncommitted index updates of a record to be queried and retrieved if necessary. However, the latter enables a quick, high level screening capability to avoid the need for the slower database access in many common cases.
Information about uncommitted deletes is managed only in an in-memory data structure, because it is unnecessary to store the full record in the case of an uncommitted delete in one context; all other contexts still have access to the full record. It is simply the knowledge of the delete action that must be managed and shared.
Concurrent access to the uncommitted delete information and to the high level screening structures for the insert and update information is managed via simple monitors by using synchronized blocks on 3 lock objects, one for each action type. In some cases, we need to synchronize on both the change lock and the delete lock simultaneously. In such cases, we avoid deadlock by always synchronizing on the change lock first, then the delete lock.
To maximize concurrent access when it is determined that the dirty database must be consulted, this implementation uses a lock manager to serialize read (share) and write (exclusive) access to the backing database. Granularity of access for record inserts and updates is determined by the database indexes in use for a particular update or query. For instance, if a query is walking a particular index for its results, only a share lock on that single index is acquired when checking for an uncommitted record which might override a query's primary result. However, when a record is updated, an exclusive lock must be acquired on every index affected by all of the updated DMO properties, before the dirty record can be updated in the dirty database. For a newly inserted record, every index on the associated table must be exclusively locked for the uncommitted insert to be recorded in the dirty database.
DefaultDirtyShareContext
Modifier and Type | Field and Description |
---|---|
private java.lang.Object |
changeLock
Lock for changes map
|
private java.util.Map<java.lang.String,java.util.Set<java.io.Serializable>> |
changes
Dirty update ids by entity name
|
private java.util.Set<java.lang.String> |
createdTables
Set of DMO entity names for tables which are already created
|
private java.lang.Object |
deleteLock
Lock for deletes map
|
private java.util.Map<java.lang.String,java.util.Set<java.io.Serializable>> |
deletes
Dirty deleted ids by entity name
|
private P2JDialect |
dialect
Dialect of the dirty database
|
private Database |
dirtyDatabase
Associated dirty database
|
private GlobalEventManager |
eventManager
Index event manager
|
private static int |
INDEX_ID
Bogus record ID for locking at index level
|
private IndexHelper |
indexHelper
Helper object to lookup indexes
|
private java.lang.Object |
insertLock
Lock for inserts map
|
private java.util.Map<RecordIdentifier,Persistable> |
inserts
Map of record identifiers to inserted records
|
private InMemoryLockManager |
lockManager
Index lock manager
|
private static java.util.logging.Logger |
LOG
Logger
|
private static java.lang.String |
PK_PROPERTY
Name of primary key property
|
private org.hibernate.SessionFactory |
sessionFactory
Hibernate session factory
|
private java.util.Map<RecordIdentifier,java.util.Set<java.lang.String>> |
unvalidatedInserts
Map of record identifiers for new inserts to set of indexes requiring validation
|
Constructor and Description |
---|
DefaultDirtyShareManager(Database database)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
private void |
applyUpdates(java.lang.String entity,
Persistable dmo,
java.lang.String[] properties,
int[] extIndexes,
BaseDataType[] values)
Apply the given property updates to the given DMO using reflection.
|
void |
cleanupChanges(java.util.Map<java.lang.String,java.util.Set<java.io.Serializable>> subChanges,
java.util.Set<RecordIdentifier> subInserts,
java.util.Set<java.lang.String> leakedEntities)
Stop tracking uncommitted changes to the the subset of records
represented by
subChanges , and remove from the master set
of uncommitted, inserted records the subset of records represented by
subInserts . |
void |
cleanupDeletes(java.util.Map<java.lang.String,java.util.Set<java.io.Serializable>> subDeletes)
Remove from the master set of uncommitted, deleted records the subset of
records represented by
subDeletes . |
private void |
createTable(java.lang.String entity)
Given the name of an entity representing a database table and DMO type,
this method will create the "dirty" table and its associated indexes,
within the associated "dirty" database.
|
void |
delete(java.lang.String entity,
java.io.Serializable id,
boolean rollback,
boolean lock)
Mark a record as having been deleted in an uncommitted transaction, or
unmark a record which previously was so marked.
|
void |
deregisterForGlobalEvents(long registerID)
Deregister with a global event clearinghouse an interest in insert,
delete, and update events which affect a particular DMO type.
|
Persistable |
getDirtyDMO(java.lang.String entity,
java.io.Serializable id)
Retrieve from the dirty database the record specified by the given
entity and primary key, if it exists.
|
DirtyInfo |
getDirtyInfo(java.lang.String entity,
java.io.Serializable candidateID,
java.lang.String index,
java.util.List<java.lang.String> statements,
java.lang.Object[] params,
org.hibernate.type.Type[] types,
boolean rowidLookup)
Given certain search criteria and possibly the primary key of a
potential DMO match in the primary database, report any significant
information currently being tracked for uncommitted transactions, which
might override data (or the lack thereof) found in the primary database.
|
int |
getEntityDirtyState(java.lang.String entity)
Indicate whether any uncommitted modification is being tracked for the
database table associated with the specified entity.
|
GlobalChangeEvent[] |
getGlobalEvents(long registerID,
long lastID)
Retrieve any new events that have been collected by a global event
clearinghouse, representing inserts, deletes, and updates made to
record types for which the caller previously has registered interest.
|
private java.util.List<java.lang.String> |
indexesForProperties(java.lang.String entity,
java.lang.String[] properties)
Retrieve the names of all indexes in which each of the given DMO
properties participate and merge them into a single list sorted in
ascending alphabetical order, discarding duplicates.
|
void |
insert(java.lang.String entity,
Persistable copy,
java.util.Collection<java.lang.String> uniqueIndexes,
boolean lock)
Begin tracking a newly inserted record in the dirty database.
|
boolean |
isDeleted(java.lang.String entity,
java.io.Serializable id)
Indicate whether the record specified by the given entity and primary
key has been deleted within an uncommitted transaction in any
context.
|
boolean |
isTracked(java.lang.String entity,
java.io.Serializable id)
Indicate whether the record specified by the given entity and primary
key is being tracked for changes within an uncommitted transaction.
|
boolean |
isUnvalidatedIndex(RecordIdentifier ident,
java.lang.String index)
Indicate whether the record identified by
ident represents a newly inserted
record, which has an unvalidated index, index . |
java.util.List |
list(java.lang.String hql,
java.lang.Object[] params,
org.hibernate.type.Type[] types,
int maxResults,
int startOffset,
boolean readOnly)
Execute an HQL query and return the results as a list.
|
void |
lockAllIndexes(java.lang.String entity,
LockType lockType)
Lock or unlock all indexes associated with the given DMO entity.
|
private void |
lockMultiple(java.util.List<java.lang.String> names,
LockType lockType)
Attempts to acquire multiple locks of the type specified, on the indexes
represented by
names , or to release existing locks on those
indexes. |
private void |
lockSingle(java.lang.String name,
LockType lockType)
Attempt to acquire a lock of the type specified on a single index, or to
release an existing lock.
|
void |
notifyInsertValidated(RecordIdentifier ident,
Persistable copy)
Notify the dirty share manager that the given record has been validated, and should no
longer be tracked as unvalidated.
|
private java.lang.Object[] |
preprocessQueryParameters(java.lang.Object[] params)
Preprocess an array of query parameters appropriate to the dirty database's dialect.
|
long |
registerForGlobalEvents(java.lang.String entity)
Register with a global event clearinghouse an interest in insert,
delete, and update events which affect the given DMO entity.
|
private void |
removeRecords(java.lang.String entity,
java.util.Set<java.io.Serializable> ids)
Stop tracking uncommitted changes to the the specified set of records
associated with the given entity name.
|
void |
rollbackInsert(RecordIdentifier ident,
boolean lock)
Rollback the insert of a record previously introduced with the
insert(String, Persistable, Collection, boolean) method. |
private void |
trackChange(java.lang.String entity,
Persistable copy,
java.util.List<java.lang.String> lockIndexes,
java.lang.String[] properties,
boolean insert,
boolean early,
java.util.Collection<java.lang.String> uniqueIndexes)
Begin tracking changes which occur in the calling context's current
transaction for the given DMO.
|
void |
update(java.lang.String entity,
Persistable copy,
java.lang.String[] properties,
int[] extIndexes,
BaseDataType[] values,
java.util.Collection<java.lang.String> validatedIndexes,
boolean lock)
Begin tracking a DMO for changes, based on the updates indicated by the
properties , extIndexes and values arguments. |
void |
update(java.lang.String entity,
java.io.Serializable id,
java.lang.String[] properties,
int[] extIndexes,
BaseDataType[] values,
java.util.Collection<java.lang.String> validatedUniqueIndexes,
boolean validatedTransientIndex,
boolean lock)
Retrieve a DMO which is being tracked in the dirty database, and apply the specified updates
to it, as provided by the
properties , extIndexes and values
arguments. |
void |
updateSnapshots(java.lang.String entity,
Persistable[] dmos)
Overwrite the state of the records in the dirty database which match the
IDs of the given list of DMOs for the given entity, and store a snapshot
of each DMO in the map of newly inserted records.
|
private static final int INDEX_ID
private static final java.lang.String PK_PROPERTY
private static final java.util.logging.Logger LOG
private final Database dirtyDatabase
private final P2JDialect dialect
private final org.hibernate.SessionFactory sessionFactory
private final IndexHelper indexHelper
private final java.util.Set<java.lang.String> createdTables
private final InMemoryLockManager lockManager
private final GlobalEventManager eventManager
private final java.lang.Object changeLock
private final java.lang.Object deleteLock
private final java.lang.Object insertLock
private java.util.Map<RecordIdentifier,Persistable> inserts
private java.util.Map<RecordIdentifier,java.util.Set<java.lang.String>> unvalidatedInserts
private java.util.Map<java.lang.String,java.util.Set<java.io.Serializable>> changes
private java.util.Map<java.lang.String,java.util.Set<java.io.Serializable>> deletes
DefaultDirtyShareManager(Database database)
SessionFactory
.
Retrieves an IndexHelper
instance and creates a headless
LockManager
to coordinate read and write access to the
dirty database.database
- Primary database for which we are managing a dirty database.public long registerForGlobalEvents(java.lang.String entity)
registerForGlobalEvents
in interface DirtyShareManager
entity
- DMO entity for which the caller is interested in tracking
change.getGlobalEvents(long, long)
,
deregisterForGlobalEvents(long)
public void deregisterForGlobalEvents(long registerID)
deregisterForGlobalEvents
in interface DirtyShareManager
registerID
- A unique identifier for the registrant being deregistered.getGlobalEvents(long, long)
,
registerForGlobalEvents(String)
public GlobalChangeEvent[] getGlobalEvents(long registerID, long lastID) throws EventRegistrationException
getGlobalEvents
in interface DirtyShareManager
registerID
- A unique identifier for an object which has registered interest
in record-changing events.lastID
- A unique identifier representing the last event retrieved by
the caller. If less than 0, it is assumed no events have yet
been retrieved since the caller registered interest in these
events.null
if no
such events have been collected.EventRegistrationException
- if registerID
is invalid or has expired.public void lockAllIndexes(java.lang.String entity, LockType lockType) throws PersistenceException
lockAllIndexes
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.lockType
- Type of lock to acquire, or NONE
to release
existing locks. NO_WAIT
variants will be treated
as regular, blocking variants.PersistenceException
- if there is an error querying JDBC metadata while retrieving
index information.public void insert(java.lang.String entity, Persistable copy, java.util.Collection<java.lang.String> uniqueIndexes, boolean lock) throws PersistenceException
This record is removed when the adding context's current transaction is committed or rolled back.
insert
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation class associated
with a table being tracked for uncommitted changes.copy
- Copy of the record to be tracked, ready to be inserted into the dirty database.uniqueIndexes
- If the insertion is happening at record creation, and the record has not yet been
validated, this will represent the collection of unique indexes that will need to
be validated before the record can safely be persisted. If null
, this
indicates the record has been fully validated and should no longer be tracked as
unvalidated.lock
- true
to acquire write locks to insert the record; false
to assume write locks are acquired by calling code.PersistenceException
- if there is any database error.public void notifyInsertValidated(RecordIdentifier ident, Persistable copy) throws PersistenceException
copy
.notifyInsertValidated
in interface DirtyShareManager
ident
- Record identifier (using entity name and primary key).copy
- Updated copy of DMO for the dirty manager to share with other contexts.PersistenceException
- if there is any database error.public boolean isUnvalidatedIndex(RecordIdentifier ident, java.lang.String index)
ident
represents a newly inserted
record, which has an unvalidated index, index
. Assumes appropriate indexes
already are locked by the caller.isUnvalidatedIndex
in interface DirtyShareManager
ident
- Record identifier (using entity name and primary key).index
- Index to be checked for validation.true
if ident
represents a new record in a foreign
context with unvalidated index index
.public void rollbackInsert(RecordIdentifier ident, boolean lock) throws PersistenceException
insert(String, Persistable, Collection, boolean)
method.rollbackInsert
in interface DirtyShareManager
ident
- Identifier for the target record, which encapsulates its entity
name and primary key.lock
- true
to acquire write locks;
false
to assume write locks are acquired by
calling code.PersistenceException
- if there is any database error.public boolean isTracked(java.lang.String entity, java.io.Serializable id)
isTracked
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.id
- Primary key of the record to be checked.true
to indicate the target record is being
tracked for changes, else false
.public void update(java.lang.String entity, Persistable copy, java.lang.String[] properties, int[] extIndexes, BaseDataType[] values, java.util.Collection<java.lang.String> validatedIndexes, boolean lock) throws PersistenceException
properties
, extIndexes
and values
arguments.
Make a copy of the given record, apply the specified updates to that copy, and store the copy in the dirty database.
This record is removed when the adding context's current transaction is committed or rolled back.
update
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted changes.copy
- Copy of the record to be tracked.properties
- Array of names of those DMO properties which were updated.
These should represent columns which participate in one or more indexes.extIndexes
- In case of EXTENT fields this array contains their index. Otherwise -1.values
- Updated DMO property values. Each value in the array
corresponds positionally with its matching property name in the
properties
array.validatedIndexes
- Collection of unique indexes which have been checked successfully for this update
to have passed validation.lock
- true
to acquire write locks to update the record;
false
to assume write locks are acquired by calling code.PersistenceException
- if there is any database error.public void update(java.lang.String entity, java.io.Serializable id, java.lang.String[] properties, int[] extIndexes, BaseDataType[] values, java.util.Collection<java.lang.String> validatedUniqueIndexes, boolean validatedTransientIndex, boolean lock) throws PersistenceException
properties
, extIndexes
and values
arguments. It is assumed the DMO already exists in the database, from a previous call to
update(String, Persistable, String[], int[], BaseDataType[], Collection, boolean)
.update
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation class associated
with a table being tracked for uncommitted changes.id
- Primary key id of the record to be retrieved and updated.properties
- Array of names of those DMO properties which were updated. These should represent
columns which participate in one or more indexes.extIndexes
- In case of EXTENT fields this array contains their index. Otherwise -1.values
- Updated DMO property values. Each value in the array corresponds positionally with
its matching property name in the properties
array.validatedUniqueIndexes
- Collection of unique indexes which have been checked successfully for this update
to have passed validation. May be null
.validatedTransientIndex
- true
if the update was caused by an index validation of a transient record.
In this case the record will be updated in inserts
structure so the current
state will be visible to other contexts.lock
- true
to acquire write locks to update the record;
false
to assume write locks are acquired by calling code.PersistenceException
- if there is any database error.public void updateSnapshots(java.lang.String entity, Persistable[] dmos) throws PersistenceException
This is necessary to support a quirk/bug in Progress which compromises transaction isolation by leaking uncommitted changes (even non-indexed data) under certain conditions.
updateSnapshots
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.dmos
- Array of DMOs which are to be merged into their counterpart
records in the dirty database and whose snapshots are to be
stored in the map of newly inserted records.PersistenceException
- if there is any database error.public int getEntityDirtyState(java.lang.String entity)
getEntityDirtyState
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.DirtyInfo
. Zero return indicates entity is not
dirty. Only CHANGE
and DELETE
are
detected, not INSERT
.public boolean isDeleted(java.lang.String entity, java.io.Serializable id)
isDeleted
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.id
- Primary key of the record to be checked.true
if the specified record has been deleted,
else false
.public void delete(java.lang.String entity, java.io.Serializable id, boolean rollback, boolean lock) throws PersistenceException
A record is unmarked when the adding context's current transaction is committed or rolled back.
delete
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.id
- Primary key of deleted record.rollback
- If false
, the target record is marked as deleted;
if true
, it is unmarked.lock
- true
to acquire write locks to delete the record;
false
to assume write locks are acquired by
calling code.PersistenceException
- if there was an error deleting the record from the database.public Persistable getDirtyDMO(java.lang.String entity, java.io.Serializable id) throws PersistenceException
This method temporarily places a share lock on all indexes containing the primary key column for the target table.
getDirtyDMO
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.id
- Primary key of the record to be retrieved.null
.PersistenceException
- never.public DirtyInfo getDirtyInfo(java.lang.String entity, java.io.Serializable candidateID, java.lang.String index, java.util.List<java.lang.String> statements, java.lang.Object[] params, org.hibernate.type.Type[] types, boolean rowidLookup) throws PersistenceException
If a DirtyInfo
object is returned by this method, it will
contain overriding information, such as a dirty DMO which matched the
search criteria, whether that record was newly inserted, or the fact
that the candidate record found in the primary search has been deleted
or modified in an uncommitted transaction. A null
return
indicates no overriding information was available.
This method acquires a share lock on index
.
getDirtyInfo
in interface DirtyShareManager
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.candidateID
- Primary key ID of DMO, if any, found in the primary database,
which matches the current query criteria.index
- Name of index which governs the ordering of data in the current
query.statements
- One or more HQL statements to be executed against the dirty
database to find a record which matches the current query
criteria. The list is in order of most specific to least
specific search criteria.params
- Query substitution parameters which match placeholders in the
most specific HQL statement.types
- Hibernate data types of the query substitution parameters.rowidLookup
- The predicate of the query does a lookup for ROWID/RECID of the table. In case of
transient records they are accessible without the need of having a full matched
index.null
if no uncommitted change information was available for the
given arguments.PersistenceException
- if there was any database error.public java.util.List list(java.lang.String hql, java.lang.Object[] params, org.hibernate.type.Type[] types, int maxResults, int startOffset, boolean readOnly) throws PersistenceException
Object
s.
No locking is attempted.
list
in interface DirtyShareManager
hql
- HQL query statement passed to Hibernate. This method makes no
assumptions as to the types of object(s) returned.params
- Substitution values for the query. If none, this should be an
empty array.types
- Hibernate types for the values
array. 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.readOnly
- 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 void cleanupChanges(java.util.Map<java.lang.String,java.util.Set<java.io.Serializable>> subChanges, java.util.Set<RecordIdentifier> subInserts, java.util.Set<java.lang.String> leakedEntities) throws PersistenceException
subChanges
, and remove from the master set
of uncommitted, inserted records the subset of records represented by
subInserts
.cleanupChanges
in interface DirtyShareManager
subChanges
- Sets of primary keys representing those records to be removed
from uncommitted change tracking, mapped by entity name.subInserts
- A set of identifiers of those records to be removed from the
master set of uncommitted inserts.leakedEntities
- Names of DMO types which have had their uncommitted updates
"leaked" to other sessions via updateSnapshots(String,
Persistable[])
.PersistenceException
- if there is any database error.public void cleanupDeletes(java.util.Map<java.lang.String,java.util.Set<java.io.Serializable>> subDeletes)
subDeletes
.cleanupDeletes
in interface DirtyShareManager
subDeletes
- Sets of primary keys representing those records to be removed
from uncommitted delete tracking, mapped by entity name.private void removeRecords(java.lang.String entity, java.util.Set<java.io.Serializable> ids) throws PersistenceException
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.ids
- Set of primary key IDs of the records to be removed from
tracking.PersistenceException
- if there is any database error.private void lockSingle(java.lang.String name, LockType lockType)
If invoked with a lockType
that is not NONE
,
this method will block if a target lock is currently unavailable
(NO_WAIT
lock type variants are treated as regular,
blocking lock types).
name
- Name of the index to lock.lockType
- Type of lock to acquire, or NONE
to release an
existing lock. NO_WAIT
variants will be treated
as regular, blocking variants.LockManager
private void lockMultiple(java.util.List<java.lang.String> names, LockType lockType)
names
, or to release existing locks on those
indexes.
If invoked with a lockType
that is not NONE
,
this method will block if a target lock is currently unavailable
(NO_WAIT
lock type variants are treated as regular,
blocking lock types).
names
- Names of the indexes to lock. To prevent deadlocks, this list
should be consistently ordered for calls made across different
contexts. An ascending alphabetical sort is recommended.lockType
- Type of lock to acquire, or NONE
to release
existing locks. NO_WAIT
variants will be treated
as regular, blocking variants.private java.util.List<java.lang.String> indexesForProperties(java.lang.String entity, java.lang.String[] properties) throws PersistenceException
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.properties
- Array of property names for which index names are to be
retrieved.PersistenceException
- if an error occurs querying index metadata.private void trackChange(java.lang.String entity, Persistable copy, java.util.List<java.lang.String> lockIndexes, java.lang.String[] properties, boolean insert, boolean early, java.util.Collection<java.lang.String> uniqueIndexes) throws PersistenceException
This method acquires exclusive locks on all the indexes in the
indexes
parameter.
entity
- Name of an entity, which is the name of the DMO implementation
class associated with a table being tracked for uncommitted
changes.copy
- Copy of the DMO being tracked.lockIndexes
- List of indexes to lock while recording the uncommitted changes. If
null
, no locking is attempted.properties
- Array of names of those DMO properties which have been updated.insert
- true
if the record was newly inserted into its
primary database, false
if the record previously
existed in the primary database and is simply being updated
now.early
- true
to indicate the insertion is happening at record creation, and
the record has not yet been validated; false
to indicate the insertion
is happening at another point, such as a rollback of a deletion, or that this
method is being called again upon validation of a new record, and the now-validated
record should no longer be tracked as unvalidated.uniqueIndexes
- If early
is true
, this represents the unique indexes
which must be checked for this record to fully pass validation. If
early
is false
, this represents the unique indexes which
were validated for this record for this change set.PersistenceException
- if there is any database error.private void applyUpdates(java.lang.String entity, Persistable dmo, java.lang.String[] properties, int[] extIndexes, BaseDataType[] values) throws PersistenceException
entity
- Name of an entity, which is the name of the DMO implementation class associated
with a table being tracked for uncommitted changes.dmo
- DMO being updated.properties
- Array of names of those DMO properties which are being updated.extIndexes
- Array of 0-base indexes of EXTENT DMO properties. Otherwise -1.values
- Updated DMO property values. Each value in the array corresponds positionally with
its matching property name in the properties
array.PersistenceException
- if there is any error applying updates.private java.lang.Object[] preprocessQueryParameters(java.lang.Object[] params)
params
- Query parameters. If none, this should be a 0-length array.private void createTable(java.lang.String entity) throws PersistenceException
entity
- Name of an entity, which is the name of the DMO implementation
class associated with the table being created.PersistenceException
- if there is any database error.