Methods Summary |
---|
public void | clearForClose(boolean shouldClearCache)INTERNAL:
Call this method if the uow will no longer used for comitting transactions:
all the changes sets will be dereferenced, and (optionally) the cache cleared.
If the uow is not released, but rather kept around for ValueHolders, then identity maps shouldn't be cleared:
the parameter value should be 'false'. The lifecycle set to Birth so that uow ValueHolder still could be used.
Alternatively, if called from release method then everything should go and therefore parameter value should be 'true'.
In this case lifecycle won't change - uow.release (optionally) calls this method when it (uow) is already dead.
The reason for calling this method from release is to free maximum memory right away:
the uow might still be referenced by objects using UOWValueHolders (though they shouldn't be around
they still might).
super.clearForClose(shouldClearCache);
this.cumulativeUOWChangeSet = null;
this.unregisteredDeletedObjectsCloneToBackupAndOriginal = null;
|
public void | commitRootUnitOfWork()INTERNAL:
Commit the changes to any objects to the parent.
commitToDatabaseWithChangeSet(false);
// unit of work has been committed so it's ok to set the cumulative into the UOW for merge
if(this.cumulativeUOWChangeSet != null) {
this.cumulativeUOWChangeSet.mergeUnitOfWorkChangeSet((UnitOfWorkChangeSet)this.getUnitOfWorkChangeSet(), this, true);
setUnitOfWorkChangeSet(this.cumulativeUOWChangeSet);
}
commitTransactionAfterWriteChanges(); // this method will commit the transaction
// and set the transaction flags appropriately
// Merge after commit
mergeChangesIntoParent();
|
protected void | commitToDatabase(boolean commitTransaction)INTERNAL:
Wraps the oracle.toplink.essentials.exceptions.OptimisticLockException in a
javax.persistence.OptimisticLockException. This conforms to the EJB3 specs
try {
super.commitToDatabase(commitTransaction);
} catch (oracle.toplink.essentials.exceptions.OptimisticLockException ole) {
throw new javax.persistence.OptimisticLockException(ole);
}
|
public void | commitTransaction()INTERNAL:
This is internal to the uow, transactions should not be used explictly in a uow.
The uow shares its parents transactions.
if (this.shouldTerminateTransaction || getParent().getTransactionMutex().isNested()){
super.commitTransaction();
}
|
public void | discoverUnregisteredNewObjects(java.lang.Object clone, oracle.toplink.essentials.internal.helper.IdentityHashtable knownNewObjects, oracle.toplink.essentials.internal.helper.IdentityHashtable unregisteredExistingObjects, oracle.toplink.essentials.internal.helper.IdentityHashtable visitedObjects)INTERNAL:
Traverse the object to find references to objects not registered in this unit of work.
// This define an inner class for process the itteration operation, don't be scared, its just an inner class.
DescriptorIterator iterator = new DescriptorIterator() {
public void iterate(Object object) {
// If the object is read-only the do not continue the traversal.
if (isClassReadOnly(object.getClass()) || isObjectDeleted(object)) {
this.setShouldBreak(true);
return;
}
//check for null mapping, this may be the first iteration
if ((getCurrentMapping() != null) && ((ForeignReferenceMapping)getCurrentMapping()).isCascadePersist() ){
((RepeatableWriteUnitOfWork)getSession()).registerNewObjectForPersist(object, new IdentityHashtable());
}else{
if (!getCloneMapping().containsKey(object)){
if (! checkForUnregisteredExistingObject(object)){
throw new IllegalStateException(ExceptionLocalization.buildMessage("new_object_found_during_commit", new Object[]{object}));
}else{
((IdentityHashtable)getUnregisteredExistingObjects()).put(object, object);
this.setShouldBreak(true);
return;
}
}
}
}
};
//set the collection in the UnitofWork to be this list
setUnregisteredExistingObjects(unregisteredExistingObjects);
iterator.setVisitedObjects(visitedObjects);
iterator.setResult(knownNewObjects);
iterator.setSession(this);
// When using wrapper policy in EJB the iteration should stop on beans,
// this is because EJB forces beans to be registered anyway and clone identity can be violated
// and the violated clones references to session objects should not be traversed.
iterator.setShouldIterateOverWrappedObjects(false);
iterator.startIterationOn(clone);
|
public java.lang.Object | getUnregisteredDeletedCloneForOriginal(java.lang.Object original)INTERNAL:
Called only by UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent method.
Return unregisteredDeletedClone corresponding to the passed original, or null
if(unregisteredDeletedObjectsCloneToBackupAndOriginal != null) {
Enumeration keys = unregisteredDeletedObjectsCloneToBackupAndOriginal.keys();
Enumeration values = unregisteredDeletedObjectsCloneToBackupAndOriginal.elements();
while(keys.hasMoreElements()) {
Object deletedObjectClone = keys.nextElement();
Object[] backupAndOriginal = (Object[])values.nextElement();
Object currentOriginal = backupAndOriginal[1];
if(original == currentOriginal) {
return deletedObjectClone;
}
}
}
return null;
|
public boolean | isAfterWriteChangesButBeforeCommit()INTERNAL:
Has writeChanges() been attempted on this UnitOfWork? It may have
either suceeded or failed but either way the UnitOfWork is in a highly
restricted state.
//dont' check for writechanges failure.
return (getLifecycle() == CommitTransactionPending);
|
public boolean | isObjectDeleted(java.lang.Object object)INTERNAL:
Return if the object has been deleted in this unit of work.
if(super.isObjectDeleted(object)) {
return true;
} else {
if(unregisteredDeletedObjectsCloneToBackupAndOriginal != null) {
if(unregisteredDeletedObjectsCloneToBackupAndOriginal.containsKey(object)) {
return true;
}
}
if (hasObjectsDeletedDuringCommit()) {
return getObjectsDeletedDuringCommit().containsKey(object);
} else {
return false;
}
}
|
public void | issueSQLbeforeCompletion()INTERNAL:
For synchronized units of work, dump SQL to database
super.issueSQLbeforeCompletion(false);
if (this.cumulativeUOWChangeSet != null && this.getUnitOfWorkChangeSet() != null){
// unit of work has been committed so it's ok to set the cumulative into the UOW for merge
this.cumulativeUOWChangeSet.mergeUnitOfWorkChangeSet((UnitOfWorkChangeSet)this.getUnitOfWorkChangeSet(), this, true);
setUnitOfWorkChangeSet(this.cumulativeUOWChangeSet);
}
commitTransactionAfterWriteChanges(); // this method will commit the transaction
// and set the transaction flags appropriately
|
public java.lang.Object | mergeCloneWithReferences(java.lang.Object rmiClone, int cascadePolicy, boolean forceCascade)INTERNAL:
Merge the attributes of the clone into the unit of work copy.
Object mergedObject = super.mergeCloneWithReferences(rmiClone, cascadePolicy, forceCascade);
if (mergedObject != null) {
// This will assign a sequence number to the merged object if it
// doesn't already have one (that is, it is a new object).
assignSequenceNumber(mergedObject);
}
return mergedObject;
|
protected void | registerNotRegisteredNewObjectForPersist(java.lang.Object newObject, oracle.toplink.essentials.descriptors.ClassDescriptor descriptor)INTERNAL:
Called only by registerNewObjectForPersist method,
and only if newObject is not already registered.
If newObject is found in
unregisteredDeletedObjectsCloneToBackupAndOriginal then it's re-registered,
otherwise the superclass method called.
if(unregisteredDeletedObjectsCloneToBackupAndOriginal != null) {
Object[] backupAndOriginal = (Object[])unregisteredDeletedObjectsCloneToBackupAndOriginal.remove(newObject);
if(backupAndOriginal != null) {
// backup
getCloneMapping().put(newObject, backupAndOriginal[0]);
// original
registerNewObjectClone(newObject, backupAndOriginal[1], descriptor);
// Check if the new objects should be cached.
registerNewObjectInIdentityMap(newObject, newObject);
return;
}
}
super.registerNotRegisteredNewObjectForPersist(newObject, descriptor);
|
public void | rollbackTransaction()INTERNAL:
This is internal to the uow, transactions should not be used explictly in a uow.
The uow shares its parents transactions.
if (this.shouldTerminateTransaction || getParent().getTransactionMutex().isNested()){
super.rollbackTransaction();
}else{
//rollback called which means txn failed.
//but rollback was stopped by entitytransaction which means the
//transaction will want to call release later. Make sure release
//will rollback transaction.
setWasTransactionBegunPrematurely(true);
}
|
public void | setShouldClearForCloseInsteadOfResume(boolean shouldClearForCloseInsteadOfResume)
this.shouldClearForCloseInsteadOfResume = shouldClearForCloseInsteadOfResume;
|
public void | setShouldTerminateTransaction(boolean shouldTerminateTransaction)
this.shouldTerminateTransaction = shouldTerminateTransaction;
|
public boolean | shouldClearForCloseInsteadOfResume()
return shouldClearForCloseInsteadOfResume;
|
public boolean | shouldClearForCloseOnRelease()INTERNAL:
Indicates whether clearForClose methor should be called by release method.
return true;
|
public void | synchronizeAndResume()INTERNAL
Synchronize the clones and update their backup copies.
Called after commit and commit and resume.
if(this.shouldClearForCloseInsteadOfResume()) {
this.clearForClose(false);
} else {
this.cumulativeUOWChangeSet = null;
this.unregisteredDeletedObjectsCloneToBackupAndOriginal = null;
super.synchronizeAndResume();
}
|
public void | updateChangeTrackersIfRequired(java.lang.Object objectToWrite, oracle.toplink.essentials.internal.sessions.ObjectChangeSet changeSetToWrite, oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl uow, oracle.toplink.essentials.descriptors.ClassDescriptor descriptor)INTERNAL:
This method is used internally to update the tracked objects if required
descriptor.getObjectChangePolicy().updateWithChanges(objectToWrite, changeSetToWrite, uow, descriptor);
|
public void | writeChanges()INTERNAL:
This method will cause the all of the tracked objects at this level to have
their changes written to the database. It will then decrement the depth
level.
if(unregisteredDeletedObjectsCloneToBackupAndOriginal == null) {
unregisteredDeletedObjectsCloneToBackupAndOriginal = new IdentityHashtable(2);
}
IdentityHashtable allObjectsList = new IdentityHashtable();
IdentityHashtable visitedNodes = new IdentityHashtable(2);
IdentityHashtable newObjects = new IdentityHashtable(2);
IdentityHashtable existingObjects = new IdentityHashtable(2);
IdentityHashtable insertedNewObjects = new IdentityHashtable(2);
for (Enumeration clones = getCloneMapping().keys(); clones.hasMoreElements();){
Object object = clones.nextElement();
discoverUnregisteredNewObjects(object, newObjects, existingObjects, visitedNodes);
allObjectsList.put(object, object);
}
for (Enumeration newClones = getNewObjectsCloneToOriginal().keys();newClones.hasMoreElements();){
Object object = newClones.nextElement();
assignSequenceNumber(object);
insertedNewObjects.put(object, object);
// add potentially newly discovered new objects
allObjectsList.put(object, object);
}
if (getUnitOfWorkChangeSet() == null) {
setUnitOfWorkChangeSet(new UnitOfWorkChangeSet());
}
calculateChanges(allObjectsList, (UnitOfWorkChangeSet)getUnitOfWorkChangeSet());
// write those changes to the database.
UnitOfWorkChangeSet changeSet = (UnitOfWorkChangeSet)getUnitOfWorkChangeSet();
if (!changeSet.hasChanges() && !changeSet.hasForcedChanges() && ! this.hasDeletedObjects() && ! this.hasModifyAllQueries()){
return;
}
try {
commitToDatabaseWithPreBuiltChangeSet(changeSet, false);
this.writesCompleted();
} catch (RuntimeException ex) {
setLifecycle(WriteChangesFailed);
throw ex;
}
//bug 4730595: fix puts deleted objects in the UnitOfWorkChangeSet as they are removed.
getDeletedObjects().clear();
// unregister all deleted objects,
// keep them along with their original and backup values in unregisteredDeletedObjectsCloneToBackupAndOriginal
Enumeration enumDeleted = getObjectsDeletedDuringCommit().keys();
while(enumDeleted.hasMoreElements()) {
Object deletedObject = enumDeleted.nextElement();
Object[] backupAndOriginal = {getCloneMapping().get(deletedObject), getCloneToOriginals().get(deletedObject)};
unregisteredDeletedObjectsCloneToBackupAndOriginal.put(deletedObject, backupAndOriginal);
unregisterObject(deletedObject);
}
getObjectsDeletedDuringCommit().clear();
if(this.cumulativeUOWChangeSet == null) {
this.cumulativeUOWChangeSet = (UnitOfWorkChangeSet)getUnitOfWorkChangeSet();
} else {
//merge those changes back into the backup clones and the final uowChangeSet
this.cumulativeUOWChangeSet.mergeUnitOfWorkChangeSet((UnitOfWorkChangeSet)getUnitOfWorkChangeSet(), this, true);
}
//clean up
setUnitOfWorkChangeSet(new UnitOfWorkChangeSet());
Enumeration enumtr = insertedNewObjects.elements();
while (enumtr.hasMoreElements()) {
Object clone = enumtr.nextElement();
Object original = getNewObjectsCloneToOriginal().remove(clone);
if (original != null) {
getNewObjectsOriginalToClone().remove(original);
//no longer new to this unit of work
getCloneToOriginals().put(clone, original);
}
}
|