Methods Summary |
---|
public void | addAction(org.hibernate.action.EntityIdentityInsertAction insert)
insertions.add( insert );
|
public void | addAction(org.hibernate.action.BulkOperationCleanupAction cleanupAction)
// Add these directly to the executions queue
executions.add( cleanupAction );
|
public void | addAction(org.hibernate.action.EntityInsertAction action)
insertions.add( action );
|
public void | addAction(org.hibernate.action.EntityDeleteAction action)
deletions.add( action );
|
public void | addAction(org.hibernate.action.EntityUpdateAction action)
updates.add( action );
|
public void | addAction(org.hibernate.action.CollectionRecreateAction action)
collectionCreations.add( action );
|
public void | addAction(org.hibernate.action.CollectionRemoveAction action)
collectionRemovals.add( action );
|
public void | addAction(org.hibernate.action.CollectionUpdateAction action)
collectionUpdates.add( action );
|
public void | afterTransactionCompletion(boolean success)Performs cleanup of any held cache softlocks.
int size = executions.size();
final boolean invalidateQueryCache = session.getFactory().getSettings().isQueryCacheEnabled();
for ( int i = 0; i < size; i++ ) {
try {
Executable exec = ( Executable ) executions.get(i);
try {
exec.afterTransactionCompletion( success );
}
finally {
if ( invalidateQueryCache ) {
session.getFactory().getUpdateTimestampsCache().invalidate( exec.getPropertySpaces() );
}
}
}
catch (CacheException ce) {
log.error( "could not release a cache lock", ce );
// continue loop
}
catch (Exception e) {
throw new AssertionFailure( "Exception releasing cache locks", e );
}
}
executions.clear();
|
public boolean | areInsertionsOrDeletionsQueued()Check whether any insertion or deletion actions are currently queued.
return ( insertions.size() > 0 || deletions.size() > 0 );
|
public boolean | areTablesToBeUpdated(java.util.Set tables)Check whether the given tables/query-spaces are to be executed against
given the currently queued actions.
return areTablesToUpdated( updates, tables ) ||
areTablesToUpdated( insertions, tables ) ||
areTablesToUpdated( deletions, tables ) ||
areTablesToUpdated( collectionUpdates, tables ) ||
areTablesToUpdated( collectionCreations, tables ) ||
areTablesToUpdated( collectionRemovals, tables );
|
private static boolean | areTablesToUpdated(java.util.List executables, java.util.Set tablespaces)
int size = executables.size();
for ( int j = 0; j < size; j++ ) {
Serializable[] spaces = ( (Executable) executables.get(j) ).getPropertySpaces();
for ( int i = 0; i < spaces.length; i++ ) {
if ( tablespaces.contains( spaces[i] ) ) {
if ( log.isDebugEnabled() ) log.debug( "changes must be flushed to space: " + spaces[i] );
return true;
}
}
}
return false;
|
public void | clear()
updates.clear();
insertions.clear();
deletions.clear();
collectionCreations.clear();
collectionRemovals.clear();
collectionUpdates.clear();
|
public void | clearFromFlushNeededCheck(int previousCollectionRemovalSize)
collectionCreations.clear();
collectionUpdates.clear();
updates.clear();
// collection deletions are a special case since update() can add
// deletions of collections not loaded by the session.
for ( int i = collectionRemovals.size()-1; i >= previousCollectionRemovalSize; i-- ) {
collectionRemovals.remove(i);
}
|
public java.util.ArrayList | cloneDeletions()
return (ArrayList) deletions.clone();
|
public static org.hibernate.engine.ActionQueue | deserialize(java.io.ObjectInputStream ois, SessionImplementor session)Used by the owning session to explicitly control deserialization of the
action queue
log.trace( "deserializing action-queue" );
ActionQueue rtn = new ActionQueue( session );
int queueSize = ois.readInt();
log.trace( "starting deserialization of [" + queueSize + "] insertions entries" );
rtn.insertions = new ArrayList( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
rtn.insertions.add( ois.readObject() );
}
queueSize = ois.readInt();
log.trace( "starting deserialization of [" + queueSize + "] deletions entries" );
rtn.deletions = new ArrayList( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
rtn.deletions.add( ois.readObject() );
}
queueSize = ois.readInt();
log.trace( "starting deserialization of [" + queueSize + "] updates entries" );
rtn.updates = new ArrayList( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
rtn.updates.add( ois.readObject() );
}
queueSize = ois.readInt();
log.trace( "starting deserialization of [" + queueSize + "] collectionUpdates entries" );
rtn.collectionUpdates = new ArrayList( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
rtn.collectionUpdates.add( ois.readObject() );
}
queueSize = ois.readInt();
log.trace( "starting deserialization of [" + queueSize + "] collectionRemovals entries" );
rtn.collectionRemovals = new ArrayList( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
rtn.collectionRemovals.add( ois.readObject() );
}
queueSize = ois.readInt();
log.trace( "starting deserialization of [" + queueSize + "] collectionCreations entries" );
rtn.collectionCreations = new ArrayList( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
rtn.collectionCreations.add( ois.readObject() );
}
return rtn;
|
public void | execute(org.hibernate.action.Executable executable)
final boolean lockQueryCache = session.getFactory().getSettings().isQueryCacheEnabled();
if ( executable.hasAfterTransactionCompletion() || lockQueryCache ) {
executions.add( executable );
}
if (lockQueryCache) {
session.getFactory()
.getUpdateTimestampsCache()
.preinvalidate( executable.getPropertySpaces() );
}
executable.execute();
|
public void | executeActions()Perform all currently queued actions.
executeActions( insertions );
executeActions( updates );
executeActions( collectionRemovals );
executeActions( collectionUpdates );
executeActions( collectionCreations );
executeActions( deletions );
|
private void | executeActions(java.util.List list)
int size = list.size();
for ( int i = 0; i < size; i++ ) {
execute( (Executable) list.get(i) );
}
list.clear();
session.getBatcher().executeBatch();
|
public void | executeInserts()Perform all currently queued entity-insertion actions.
executeActions( insertions );
|
public boolean | hasAnyQueuedActions()
return updates.size() > 0 ||
insertions.size() > 0 ||
deletions.size() > 0 ||
collectionUpdates.size() > 0 ||
collectionRemovals.size() > 0 ||
collectionCreations.size() > 0;
|
private void | init()
insertions = new ArrayList( INIT_QUEUE_LIST_SIZE );
deletions = new ArrayList( INIT_QUEUE_LIST_SIZE );
updates = new ArrayList( INIT_QUEUE_LIST_SIZE );
collectionCreations = new ArrayList( INIT_QUEUE_LIST_SIZE );
collectionRemovals = new ArrayList( INIT_QUEUE_LIST_SIZE );
collectionUpdates = new ArrayList( INIT_QUEUE_LIST_SIZE );
executions = new ArrayList( INIT_QUEUE_LIST_SIZE * 3 );
|
public int | numberOfCollectionCreations()
return collectionCreations.size();
|
public int | numberOfCollectionRemovals()
return collectionRemovals.size();
|
public int | numberOfCollectionUpdates()
return collectionUpdates.size();
|
public int | numberOfDeletions()
return deletions.size();
|
public int | numberOfInsertions()
return insertions.size();
|
public int | numberOfUpdates()
return updates.size();
|
public void | prepareActions()Prepares the internal action queues for execution.
prepareActions( collectionRemovals );
prepareActions( collectionUpdates );
prepareActions( collectionCreations );
|
private void | prepareActions(java.util.List queue)
int size = queue.size();
for ( int i=0; i<size; i++ ) {
Executable executable = ( Executable ) queue.get(i);
executable.beforeExecutions();
}
|
public void | serialize(java.io.ObjectOutputStream oos)Used by the owning session to explicitly control serialization of the
action queue
log.trace( "serializing action-queue" );
int queueSize = insertions.size();
log.trace( "starting serialization of [" + queueSize + "] insertions entries" );
oos.writeInt( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
oos.writeObject( insertions.get( i ) );
}
queueSize = deletions.size();
log.trace( "starting serialization of [" + queueSize + "] deletions entries" );
oos.writeInt( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
oos.writeObject( deletions.get( i ) );
}
queueSize = updates.size();
log.trace( "starting serialization of [" + queueSize + "] updates entries" );
oos.writeInt( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
oos.writeObject( updates.get( i ) );
}
queueSize = collectionUpdates.size();
log.trace( "starting serialization of [" + queueSize + "] collectionUpdates entries" );
oos.writeInt( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
oos.writeObject( collectionUpdates.get( i ) );
}
queueSize = collectionRemovals.size();
log.trace( "starting serialization of [" + queueSize + "] collectionRemovals entries" );
oos.writeInt( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
oos.writeObject( collectionRemovals.get( i ) );
}
queueSize = collectionCreations.size();
log.trace( "starting serialization of [" + queueSize + "] collectionCreations entries" );
oos.writeInt( queueSize );
for ( int i = 0; i < queueSize; i++ ) {
oos.writeObject( collectionCreations.get( i ) );
}
|
public void | sortActions()
if ( session.getFactory().getSettings().isOrderUpdatesEnabled() ) {
//sort the updates by pk
java.util.Collections.sort( updates );
}
if ( session.getFactory().getSettings().isOrderInsertsEnabled() ) {
sortInsertActions();
}
|
public void | sortCollectionActions()
if ( session.getFactory().getSettings().isOrderUpdatesEnabled() ) {
//sort the updates by fk
java.util.Collections.sort( collectionCreations );
java.util.Collections.sort( collectionUpdates );
java.util.Collections.sort( collectionRemovals );
}
|
private void | sortInsertActions()Order the {@link #insertions} queue such that we group inserts
against the same entity together (without violating constraints). The
original order is generated by cascade order, which in turn is based on
the directionality of foreign-keys. So even though we will be changing
the ordering here, we need to make absolutely certain that we do not
circumvent this FK ordering to the extent of causing constraint
violations
// IMPLEMENTATION NOTES:
//
// The main data structure in this ordering algorithm is the 'positionToAction'
// map. Essentially this can be thought of as an put-ordered map (the problem with
// actually implementing it that way and doing away with the 'nameList' is that
// we'd end up having potential duplicate key values). 'positionToAction' maitains
// a mapping from a position within the 'nameList' structure to a "partial queue"
// of actions.
HashMap positionToAction = new HashMap();
List nameList = new ArrayList();
loopInsertion: while( !insertions.isEmpty() ) {
EntityInsertAction action = ( EntityInsertAction ) insertions.remove( 0 );
String thisEntityName = action.getEntityName();
// see if we have already encountered this entity-name...
if ( ! nameList.contains( thisEntityName ) ) {
// we have not, so create the proper entries in nameList and positionToAction
ArrayList segmentedActionQueue = new ArrayList();
segmentedActionQueue.add( action );
nameList.add( thisEntityName );
positionToAction.put( new Integer( nameList.indexOf( thisEntityName ) ), segmentedActionQueue );
}
else {
// we have seen it before, so we need to determine if this insert action is
// is depenedent upon a previously processed action in terms of FK
// relationships (this FK checking is done against the entity's property-state
// associated with the action...)
int lastPos = nameList.lastIndexOf( thisEntityName );
Object[] states = action.getState();
for ( int i = 0; i < states.length; i++ ) {
for ( int j = 0; j < nameList.size(); j++ ) {
ArrayList tmpList = ( ArrayList ) positionToAction.get( new Integer( j ) );
for ( int k = 0; k < tmpList.size(); k++ ) {
final EntityInsertAction checkAction = ( EntityInsertAction ) tmpList.get( k );
if ( checkAction.getInstance() == states[i] && j > lastPos ) {
// 'checkAction' is inserting an entity upon which 'action'
// depends...
// note: this is an assumption and may not be correct in the case of one-to-one
ArrayList segmentedActionQueue = new ArrayList();
segmentedActionQueue.add( action );
nameList.add( thisEntityName );
positionToAction.put(new Integer( nameList.lastIndexOf( thisEntityName ) ), segmentedActionQueue );
continue loopInsertion;
}
}
}
}
ArrayList actionQueue = ( ArrayList ) positionToAction.get( new Integer( lastPos ) );
actionQueue.add( action );
}
}
// now iterate back through positionToAction map and move entityInsertAction back to insertion list
for ( int p = 0; p < nameList.size(); p++ ) {
ArrayList actionQueue = ( ArrayList ) positionToAction.get( new Integer( p ) );
Iterator itr = actionQueue.iterator();
while ( itr.hasNext() ) {
insertions.add( itr.next() );
}
}
|
public java.lang.String | toString()Returns a string representation of the object.
return new StringBuffer()
.append("ActionQueue[insertions=").append(insertions)
.append(" updates=").append(updates)
.append(" deletions=").append(deletions)
.append(" collectionCreations=").append(collectionCreations)
.append(" collectionRemovals=").append(collectionRemovals)
.append(" collectionUpdates=").append(collectionUpdates)
.append("]")
.toString();
|