use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class ArrayCollectionMappingHelper method mergeChangesIntoObjectWithoutOrder.
/**
* Merge changes from the source to the target object.
* Make the necessary removals and adds and map key modifications.
*/
private void mergeChangesIntoObjectWithoutOrder(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
EISCollectionChangeRecord sdkChangeRecord = (EISCollectionChangeRecord) changeRecord;
ContainerPolicy cp = getContainerPolicy();
AbstractSession session = mergeManager.getSession();
Object targetCollection = null;
if (sdkChangeRecord.getOwner().isNew()) {
targetCollection = cp.containerInstance(sdkChangeRecord.getAdds().size());
} else {
targetCollection = getRealCollectionAttributeValueFromObject(target, session);
}
List removes = sdkChangeRecord.getRemoves();
List adds = sdkChangeRecord.getAdds();
List changedMapKeys = sdkChangeRecord.getChangedMapKeys();
synchronized (targetCollection) {
for (Object removed : removes) {
Object removeElement = buildRemovedElementFromChangeSet(removed, mergeManager, targetSession);
Object targetElement = null;
for (Object iter = cp.iteratorFor(targetCollection); cp.hasNext(iter); ) {
targetElement = cp.next(iter, session);
if (compareElements(targetElement, removeElement, session)) {
// matching element found - skip the rest of them
break;
}
}
if (targetElement != null) {
// a matching element was found, remove it
cp.removeFrom(targetElement, targetCollection, session);
}
}
for (Object added : adds) {
Object addElement = buildAddedElementFromChangeSet(added, mergeManager, targetSession);
cp.addInto(addElement, targetCollection, session);
}
for (Object changed : changedMapKeys) {
Object changedMapKeyElement = buildAddedElementFromChangeSet(changed, mergeManager, targetSession);
Object originalElement = ((UnitOfWorkImpl) session).getOriginalVersionOfObject(changedMapKeyElement);
cp.removeFrom(originalElement, targetCollection, session);
cp.addInto(changedMapKeyElement, targetCollection, session);
}
}
// reset the attribute to allow for set method to re-morph changes if the collection is not being stored directly
setRealAttributeValueInObject(target, targetCollection);
}
use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class ReferenceMapping method preInsert.
/**
* INTERNAL:
* Insert privately owned parts
*/
@Override
public void preInsert(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
// Checks if privately owned parts should be inserted or not.
if (!shouldObjectModifyCascadeToParts(query)) {
return;
}
// Get the privately owned parts
Object object = getRealAttributeValueFromObject(query.getObject(), query.getSession());
if (object == null) {
return;
}
if (isPrivateOwned()) {
// No need to set changeSet as insert is a straight copy anyway
InsertObjectQuery insertQuery = new InsertObjectQuery();
insertQuery.setIsExecutionClone(true);
insertQuery.setObject(object);
insertQuery.setCascadePolicy(query.getCascadePolicy());
query.getSession().executeQuery(insertQuery);
} else {
ObjectChangeSet changeSet = null;
UnitOfWorkChangeSet uowChangeSet = null;
if (query.getSession().isUnitOfWork() && (((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet() != null)) {
uowChangeSet = (UnitOfWorkChangeSet) ((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet();
changeSet = (ObjectChangeSet) uowChangeSet.getObjectChangeSetForClone(object);
}
WriteObjectQuery writeQuery = new WriteObjectQuery();
writeQuery.setIsExecutionClone(true);
writeQuery.setObject(object);
writeQuery.setObjectChangeSet(changeSet);
writeQuery.setCascadePolicy(query.getCascadePolicy());
query.getSession().executeQuery(writeQuery);
}
}
use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class ReportQuery method executeDatabaseQuery.
/**
* INTERNAL:
* Execute the query.
* Get the rows and build the objects or report data from the rows.
* @exception DatabaseException - an error has occurred on the database
* @return either collection of objects, or report data resulting from execution of query.
*/
@Override
public Object executeDatabaseQuery() throws DatabaseException {
// ensure a pessimistic locking query will go down the write connection
if (isLockQuery() && getSession().isUnitOfWork()) {
UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl) getSession();
// transaction early on the parent also.
if (isLockQuery()) {
if ((!unitOfWork.getCommitManager().isActive()) && (!unitOfWork.wasTransactionBegunPrematurely())) {
unitOfWork.beginTransaction();
unitOfWork.setWasTransactionBegunPrematurely(true);
}
}
}
if (getContainerPolicy().overridesRead()) {
return getContainerPolicy().execute();
}
if (getQueryId() == 0) {
setQueryId(getSession().getNextQueryId());
}
setExecutionTime(System.currentTimeMillis());
if (getDescriptor().isDescriptorForInterface()) {
return getDescriptor().getInterfacePolicy().selectAllObjectsUsingMultipleTableSubclassRead(this);
}
return buildObjects(getQueryMechanism().selectAllReportQueryRows());
}
use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class AbstractSynchronizationListener method beforeCompletion.
/**
* INTERNAL:
* This method performs the logic that occurs at transaction
* completion time. This includes issuing the SQL, etc.
* This method executes within the transaction context of the caller of
* transaction.commit(), or in the case of container-managed transactions,
* in the context of the method for which the Container started the transaction.
*/
@Override
public void beforeCompletion() {
UnitOfWorkImpl uow = getUnitOfWork();
// it's a purely sequencing listener - nothing to do in beforeCompletion.
if (unitOfWork == null) {
return;
}
try {
Object status = getTransactionController().getTransactionStatus();
getTransactionController().logTxStateTrace(uow, "TX_beforeCompletion", status);
// CR# 3452053
session.startOperationProfile(SessionProfiler.JtsBeforeCompletion);
// In case jts transaction was internally started but completed
// directly by TransactionManager this flag is still set to true.
getSession().setWasJTSTransactionInternallyStarted(false);
// If the uow is not active then somebody somewhere messed up
if (!uow.isActive()) {
throw TransactionException.inactiveUnitOfWork(uow);
}
// Bail out if we don't think we should actually issue the SQL
if (!getTransactionController().canIssueSQLToDatabase_impl(status)) {
// Must force concurrency mgrs active thread if in nested transaction
if (getSession().isInTransaction()) {
getSession().getTransactionMutex().setActiveThread(Thread.currentThread());
if (getUnitOfWork().wasTransactionBegunPrematurely()) {
getUnitOfWork().setWasTransactionBegunPrematurely(false);
}
getSession().rollbackTransaction();
}
getSession().releaseJTSConnection();
return;
}
// Must force concurrency mgrs active thread if in nested transaction
if (getSession().isInTransaction()) {
getSession().getTransactionMutex().setActiveThread(Thread.currentThread());
}
// avoiding adding more listeners while processing a listener.
if (getTransactionController().isSequencingCallbackRequired()) {
getTransactionController().currentlyProcessedListeners.put(getTransactionKey(), this);
}
// Send the SQL to the DB
uow.issueSQLbeforeCompletion();
// Fix up our merge state in the unit of work and the session
uow.setPendingMerge();
} catch (RuntimeException exception) {
// Log the exception if it has not already been logged, or is a non-EclipseLink exception
if (!(exception instanceof EclipseLinkException && ((EclipseLinkException) exception).hasBeenLogged())) {
uow.logThrowable(SessionLog.WARNING, SessionLog.TRANSACTION, exception);
}
// Handle the exception according to transaction manager requirements
handleException(exception);
} finally {
if (getTransactionController().isSequencingCallbackRequired()) {
getTransactionController().currentlyProcessedListeners.remove(getTransactionKey());
}
getSession().releaseJTSConnection();
session.endOperationProfile(SessionProfiler.JtsBeforeCompletion);
}
}
use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class AbstractSynchronizationListener method afterCompletion.
/**
* INTERNAL:
* The method performs the logic that should be executed after the transaction
* has been completed. The status passed in indicates whether the transaction
* was committed or rolled back. This status flag may be different for different
* implementations.
* This method executes without a transaction context.
*
* @param status The status code of the transaction completion.
*/
public void afterCompletion(Object status) {
UnitOfWorkImpl uow = getUnitOfWork();
// it's a purely sequencing listener - call sequencing callback if the transaction has committed.
if (uow == null) {
if (getTransactionController().isSequencingCallbackRequired()) {
if (getTransactionController().canMergeUnitOfWork_impl(status)) {
callSequencingCallback();
}
}
} else {
try {
// Log the fact that we got invoked
getTransactionController().logTxStateTrace(uow, "TX_afterCompletion", status);
// Cr#3452053
this.session.startOperationProfile(SessionProfiler.JtsAfterCompletion);
// The uow should still be active even in rollback case
if (!uow.isActive()) {
throw TransactionException.inactiveUnitOfWork(uow);
}
// Only do merge if txn was committed
if (getTransactionController().canMergeUnitOfWork_impl(status)) {
if (getTransactionController().isSequencingCallbackRequired()) {
callSequencingCallback();
}
if (uow.isMergePending()) {
// uow in PENDING_MERGE state, merge clones
uow.mergeClonesAfterCompletion();
}
} else {
// call this method again because there may have been no beforeCompletion call
// if case transaction is to be rolled back.
getSession().releaseJTSConnection();
uow.afterExternalTransactionRollback();
}
// Clean up by releasing the uow and client session
if (uow.shouldResumeUnitOfWorkOnTransactionCompletion() && getTransactionController().canMergeUnitOfWork_impl(status)) {
uow.synchronizeAndResume();
uow.setSynchronized(false);
} else {
uow.release();
// Release the session explicitly
if (getSession().isClientSession() || (getSession().isSessionBroker() && ((SessionBroker) getSession()).isClientSessionBroker())) {
getSession().release();
}
}
} catch (RuntimeException exception) {
// Log the exception if it has not already been logged, or is a non-EclipseLink exception
if (!(exception instanceof EclipseLinkException && ((EclipseLinkException) exception).hasBeenLogged())) {
uow.logThrowable(SessionLog.WARNING, SessionLog.TRANSACTION, exception);
}
handleException(exception);
} finally {
getTransactionController().removeUnitOfWork(getTransactionKey());
this.session.endOperationProfile(SessionProfiler.JtsAfterCompletion);
setUnitOfWork(null);
setSession(null);
}
}
if (getTransactionController().isSequencingCallbackRequired()) {
getTransactionController().removeSequencingListener(getTransactionKey());
this.sequencingCallback = null;
this.sequencingCallbackMap = null;
}
setTransaction(null);
setTransactionKey(null);
}
Aggregations