Search in sources :

Example 1 with OptimisticLockingPolicy

use of org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy in project eclipselink by eclipse-ee4j.

the class MergeManager method mergeChangesForRefreshingRemoteObject.

/**
 * Recursively merge the RMI clone from the server
 * into the client unit of work working copy.
 * This will only be called if the working copy exists.
 */
protected Object mergeChangesForRefreshingRemoteObject(Object serverSideDomainObject) {
    ClassDescriptor descriptor = this.session.getDescriptor(serverSideDomainObject);
    Object primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(serverSideDomainObject, this.session);
    Object clientSideDomainObject = this.session.getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, serverSideDomainObject.getClass(), descriptor);
    if (clientSideDomainObject == null) {
        // the referenced object came back as null from the cache.
        ObjectDescriptor objectDescriptor = getObjectDescriptors().get(serverSideDomainObject);
        if (objectDescriptor == null) {
            // the object must have been added concurently before serialize generate a new ObjectDescriptor on this side
            objectDescriptor = new ObjectDescriptor();
            objectDescriptor.setKey(primaryKey);
            objectDescriptor.setObject(serverSideDomainObject);
            OptimisticLockingPolicy policy = descriptor.getOptimisticLockingPolicy();
            if (policy == null) {
                objectDescriptor.setWriteLockValue(null);
            } else {
                objectDescriptor.setWriteLockValue(policy.getBaseValue());
            }
        }
        // query is used for the cascade policy only
        org.eclipse.persistence.queries.ObjectLevelReadQuery query = new org.eclipse.persistence.queries.ReadObjectQuery();
        query.setCascadePolicy(this.getCascadePolicy());
        this.session.getIdentityMapAccessorInstance().putInIdentityMap(serverSideDomainObject, primaryKey, objectDescriptor.getWriteLockValue(), objectDescriptor.getReadTime(), descriptor);
        descriptor.getObjectBuilder().fixObjectReferences(serverSideDomainObject, getObjectDescriptors(), this.objectsAlreadyMerged.get(this.session), query, (DistributedSession) this.session);
        clientSideDomainObject = serverSideDomainObject;
    } else {
        // merge into the clientSideDomainObject from the serverSideDomainObject;
        // use clientSideDomainObject as the backup, as anything different should be merged
        descriptor.getObjectBuilder().mergeIntoObject(clientSideDomainObject, false, serverSideDomainObject, this, getSession());
        ObjectDescriptor objectDescriptor = getObjectDescriptors().get(serverSideDomainObject);
        if (objectDescriptor == null) {
            // the object must have been added concurently before serialize generate a new ObjectDescriptor on this side
            objectDescriptor = new ObjectDescriptor();
            objectDescriptor.setKey(primaryKey);
            objectDescriptor.setObject(serverSideDomainObject);
            OptimisticLockingPolicy policy = descriptor.getOptimisticLockingPolicy();
            if (policy == null) {
                objectDescriptor.setWriteLockValue(null);
            } else {
                objectDescriptor.setWriteLockValue(policy.getBaseValue());
            }
        }
        CacheKey key = this.session.getIdentityMapAccessorInstance().getCacheKeyForObjectForLock(primaryKey, clientSideDomainObject.getClass(), descriptor);
        // Check for null because when there is NoIdentityMap, CacheKey will be null
        if (key != null) {
            key.setReadTime(objectDescriptor.getReadTime());
        }
        if (descriptor.usesOptimisticLocking()) {
            this.session.getIdentityMapAccessor().updateWriteLockValue(primaryKey, clientSideDomainObject.getClass(), objectDescriptor.getWriteLockValue());
        }
    }
    return clientSideDomainObject;
}
Also used : ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) ObjectDescriptor(org.eclipse.persistence.internal.sessions.remote.ObjectDescriptor) CacheKey(org.eclipse.persistence.internal.identitymaps.CacheKey) OptimisticLockingPolicy(org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy)

Example 2 with OptimisticLockingPolicy

use of org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy in project eclipselink by eclipse-ee4j.

the class ReturningPolicy method verifyField.

protected static boolean verifyField(AbstractSession session, DatabaseField field, ClassDescriptor descriptor) {
    boolean ok = true;
    if (field.equals(descriptor.getSequenceNumberField())) {
        ok = false;
        session.getIntegrityChecker().handleError(DescriptorException.returningPolicyFieldNotSupported(field.getName(), descriptor));
    } else if (descriptor.hasInheritance() && field.equals(descriptor.getInheritancePolicy().getClassIndicatorField())) {
        ok = false;
        session.getIntegrityChecker().handleError(DescriptorException.returningPolicyFieldNotSupported(field.getName(), descriptor));
    } else if (descriptor.usesOptimisticLocking()) {
        OptimisticLockingPolicy optimisticLockingPolicy = descriptor.getOptimisticLockingPolicy();
        if (optimisticLockingPolicy instanceof VersionLockingPolicy) {
            VersionLockingPolicy versionLockingPolicy = (VersionLockingPolicy) optimisticLockingPolicy;
            if (field.equals(versionLockingPolicy.getWriteLockField())) {
                ok = false;
                session.getIntegrityChecker().handleError(DescriptorException.returningPolicyFieldNotSupported(field.getName(), descriptor));
            }
        }
    }
    return ok;
}
Also used : OptimisticLockingPolicy(org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy)

Example 3 with OptimisticLockingPolicy

use of org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy in project eclipselink by eclipse-ee4j.

the class DatabaseQueryMechanism method updateObjectForWriteWithChangeSet.

/**
 * Update the object.
 * This is used by the unit-of-work update.
 */
public void updateObjectForWriteWithChangeSet() {
    WriteObjectQuery writeQuery = getWriteObjectQuery();
    ObjectChangeSet changeSet = writeQuery.getObjectChangeSet();
    Object object = writeQuery.getObject();
    ClassDescriptor descriptor = getDescriptor();
    DescriptorQueryManager queryManager = descriptor.getQueryManager();
    AbstractSession session = getSession();
    CommitManager commitManager = session.getCommitManager();
    // check for user-defined query
    if (// this is not a user-defined query
    (!writeQuery.isUserDefined()) && // there is a user-defined query
    queryManager.hasUpdateQuery() && isExpressionQueryMechanism()) {
        // this is not a hand-coded call (custom SQL etc.)
        // This must be done here because the user defined update does not use a changeset so it will not be set otherwise
        commitManager.markPreModifyCommitInProgress(object);
        performUserDefinedUpdate();
        return;
    }
    // This must be done after the custom query check, otherwise it will be done twice.
    commitManager.markPreModifyCommitInProgress(object);
    DescriptorEventManager eventManager = descriptor.getEventManager();
    if (changeSet.hasChanges()) {
        // PERF: Avoid events if no listeners.
        if (eventManager.hasAnyEventListeners()) {
            DescriptorEvent event = new DescriptorEvent(DescriptorEventManager.PreUpdateWithChangesEvent, writeQuery);
            eventManager.executeEvent(event);
            // PreUpdateWithChangesEvent listeners may have altered the object - should recalculate the change set.
            UnitOfWorkChangeSet uowChangeSet = (UnitOfWorkChangeSet) ((UnitOfWorkImpl) session).getUnitOfWorkChangeSet();
            if (!uowChangeSet.isChangeSetFromOutsideUOW() && writeQuery.getObjectChangeSet().shouldRecalculateAfterUpdateEvent()) {
                // It is first cleared then re-populated by calculateChanges method.
                if (!descriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy()) {
                    // clear the change set without clearing the maps keys since they are not alterable by the event
                    // if the map is changed, it will be changed in the owning object and the
                    // change set will be changed there as well.
                    writeQuery.getObjectChangeSet().clear(false);
                }
                if (descriptor.getObjectChangePolicy().calculateChangesForExistingObject(object, uowChangeSet, ((UnitOfWorkImpl) session), descriptor, false) == null) {
                    // calculateChanges returns null in case the changeSet doesn't have changes.
                    // It should be removed from the list of ObjectChangeSets that have changes in uowChangeSet.
                    uowChangeSet.getAllChangeSets().remove(writeQuery.getObjectChangeSet());
                }
            }
        }
    }
    // Verify if deep shallow modify is turned on
    if (writeQuery.shouldCascadeParts()) {
        queryManager.preUpdate(writeQuery);
    }
    // The row must not be built until after preUpdate in case the object reference has changed.
    // For a user defined update in the uow to row must be built twice to check if any update is required.
    writeQuery.setModifyRow(descriptor.getObjectBuilder().buildRowForUpdateWithChangeSet(writeQuery));
    Boolean shouldModifyVersionField = changeSet.shouldModifyVersionField();
    if (!getModifyRow().isEmpty() || shouldModifyVersionField != null || changeSet.hasCmpPolicyForcedUpdate()) {
        // If user defined the entire row is required. Must not be built until change is known.
        if (writeQuery.isUserDefined() || writeQuery.isCallQuery()) {
            writeQuery.setModifyRow(descriptor.getObjectBuilder().buildRow(object, session, WriteType.UNDEFINED));
        }
        OptimisticLockingPolicy lockingPolicy = descriptor.getOptimisticLockingPolicy();
        // Update the write lock field if required.
        if (lockingPolicy != null) {
            lockingPolicy.addLockValuesToTranslationRow(writeQuery);
            // Do not lock an object that has previously been optimistically locked within the RWUoW
            boolean existingOptimisticLock = false;
            if (session instanceof RepeatableWriteUnitOfWork) {
                RepeatableWriteUnitOfWork uow = (RepeatableWriteUnitOfWork) session;
                if (uow.getOptimisticReadLockObjects().get(object) != null && uow.getCumulativeUOWChangeSet() != null && uow.getCumulativeUOWChangeSet().getObjectChangeSetForClone(object) != null) {
                    existingOptimisticLock = true;
                }
            }
            if (!existingOptimisticLock) {
                // or if there is no forced update and modifyRow has modifications
                if ((shouldModifyVersionField != null && shouldModifyVersionField) || !getModifyRow().isEmpty()) {
                    // Update the row with newer lock value.
                    lockingPolicy.updateRowAndObjectForUpdate(writeQuery, object);
                } else if (!shouldModifyVersionField && (lockingPolicy instanceof VersionLockingPolicy)) {
                    // Add the existing write lock value to the for a "read" lock (requires something to update).
                    ((VersionLockingPolicy) lockingPolicy).writeLockValueIntoRow(writeQuery, object);
                }
            }
        }
        if (descriptor.hasSerializedObjectPolicy()) {
            descriptor.getSerializedObjectPolicy().putObjectIntoRow(getModifyRow(), object, session);
        }
        // PERF: Avoid events if no listeners.
        if (eventManager.hasAnyEventListeners()) {
            DescriptorEvent event = new DescriptorEvent(DescriptorEventManager.AboutToUpdateEvent, writeQuery);
            event.setRecord(getModifyRow());
            eventManager.executeEvent(event);
        }
        if (QueryMonitor.shouldMonitor()) {
            QueryMonitor.incrementUpdate(getWriteObjectQuery());
        }
        int rowCount = updateObject();
        if (rowCount < 1) {
            if (session.hasEventManager()) {
                session.getEventManager().noRowsModified(writeQuery, object);
            }
        }
        if (lockingPolicy != null) {
            lockingPolicy.validateUpdate(rowCount, object, writeQuery);
        }
    }
    commitManager.markPostModifyCommitInProgress(object);
    // Verify if deep shallow modify is turned on
    if (writeQuery.shouldCascadeParts()) {
        queryManager.postUpdate(writeQuery);
    }
    if ((descriptor.getHistoryPolicy() != null) && descriptor.getHistoryPolicy().shouldHandleWrites()) {
        descriptor.getHistoryPolicy().postUpdate(writeQuery);
    }
    // PERF: Avoid events if no listeners.
    if (eventManager.hasAnyEventListeners()) {
        eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PostUpdateEvent, writeQuery));
    }
}
Also used : DescriptorQueryManager(org.eclipse.persistence.descriptors.DescriptorQueryManager) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) CommitManager(org.eclipse.persistence.internal.sessions.CommitManager) UnitOfWorkChangeSet(org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet) VersionLockingPolicy(org.eclipse.persistence.descriptors.VersionLockingPolicy) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) DescriptorEvent(org.eclipse.persistence.descriptors.DescriptorEvent) WriteObjectQuery(org.eclipse.persistence.queries.WriteObjectQuery) DescriptorEventManager(org.eclipse.persistence.descriptors.DescriptorEventManager) RepeatableWriteUnitOfWork(org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession) OptimisticLockingPolicy(org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy)

Example 4 with OptimisticLockingPolicy

use of org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy in project eclipselink by eclipse-ee4j.

the class EntityMappingsAdvancedJUnitTestCase method testProjectOptimisticLockingSettings.

/**
 * Verifies that the optimistic-locking settings were read correctly from XML.
 */
public void testProjectOptimisticLockingSettings() {
    ServerSession session = JUnitTestCase.getServerSession(m_persistenceUnit);
    ClassDescriptor descriptor = session.getDescriptor(Project.class);
    if (descriptor == null) {
        fail("Project descriptor was not found in the PU [" + m_persistenceUnit + "]");
    } else {
        OptimisticLockingPolicy policy = descriptor.getOptimisticLockingPolicy();
        if (policy instanceof SelectedFieldsLockingPolicy) {
            List<DatabaseField> lockFields = ((SelectedFieldsLockingPolicy) policy).getLockFields();
            if (lockFields.isEmpty() || lockFields.size() > 1) {
                fail("Invalid amount of lock fields were set on Project's selected fields locking policy.");
            } else {
                DatabaseField lockField = lockFields.get(0);
                assertTrue("Incorrect lock field was set on Project's selected fields locking policy.", lockField.getName().equals("VERSION"));
            }
        } else {
            fail("A SelectedFieldsLockingPolicy was not set on the Project descriptor.");
        }
    }
}
Also used : SelectedFieldsLockingPolicy(org.eclipse.persistence.descriptors.SelectedFieldsLockingPolicy) ServerSession(org.eclipse.persistence.sessions.server.ServerSession) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) OptimisticLockingPolicy(org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy)

Example 5 with OptimisticLockingPolicy

use of org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy in project eclipselink by eclipse-ee4j.

the class EntityMappingsAdvancedJUnitTestCase method testProjectOptimisticLockingSettings.

/**
 * Verifies that the optimistic-locking settings were read correctly from XML.
 */
public void testProjectOptimisticLockingSettings() {
    DatabaseSessionImpl session = getDatabaseSession();
    ClassDescriptor descriptor = session.getDescriptor(Project.class);
    if (descriptor == null) {
        fail("Project descriptor was not found in the PU [" + m_persistenceUnit + "]");
    } else {
        OptimisticLockingPolicy policy = descriptor.getOptimisticLockingPolicy();
        if (policy instanceof SelectedFieldsLockingPolicy) {
            List<DatabaseField> lockFields = ((SelectedFieldsLockingPolicy) policy).getLockFields();
            if (lockFields.isEmpty() || lockFields.size() > 1) {
                fail("Invalid amount of lock fields were set on Project's selected fields locking policy.");
            } else {
                DatabaseField lockField = lockFields.get(0);
                assertTrue("Incorrect lock field was set on Project's selected fields locking policy.", lockField.getName().equals("VERSION"));
            }
        } else {
            fail("A SelectedFieldsLockingPolicy was not set on the Project descriptor.");
        }
    }
}
Also used : SelectedFieldsLockingPolicy(org.eclipse.persistence.descriptors.SelectedFieldsLockingPolicy) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) DatabaseSessionImpl(org.eclipse.persistence.internal.sessions.DatabaseSessionImpl) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) OptimisticLockingPolicy(org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy)

Aggregations

OptimisticLockingPolicy (org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy)15 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)10 VersionLockingPolicy (org.eclipse.persistence.descriptors.VersionLockingPolicy)4 DescriptorQueryManager (org.eclipse.persistence.descriptors.DescriptorQueryManager)3 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)3 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 DescriptorEvent (org.eclipse.persistence.descriptors.DescriptorEvent)2 DescriptorEventManager (org.eclipse.persistence.descriptors.DescriptorEventManager)2 SelectedFieldsLockingPolicy (org.eclipse.persistence.descriptors.SelectedFieldsLockingPolicy)2 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)2 CommitManager (org.eclipse.persistence.internal.sessions.CommitManager)2 RepeatableWriteUnitOfWork (org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork)2 LockTimeoutException (jakarta.persistence.LockTimeoutException)1 PersistenceException (jakarta.persistence.PersistenceException)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 IdentityHashMap (java.util.IdentityHashMap)1