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;
}
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;
}
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));
}
}
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.");
}
}
}
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.");
}
}
}
Aggregations