All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.descriptors.SelectedFieldsLockingPolicy Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.descriptors;

import java.util.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.mappings.DatabaseMapping.WriteType;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.*;

/**
 * 

Purpose: An implementation of the OptimisticLockingPolicy interface. * This policy compares selected fields in the WHERE clause * when doing an update or a delete. If any field has been changed, * an optimistic locking exception will be thrown. Note that the fields * specified must be mapped and not be primary keys.

* NOTE: This policy can only be used inside a unit of work. * * @since TopLink 2.5 */ public class SelectedFieldsLockingPolicy extends FieldsLockingPolicy { protected Map lockFieldsByTable; protected Vector lockFields; /** * PUBLIC: * Create a new selected fields locking policy. * A field locking policy is based on locking on the specified fields by comparing with their previous values to detect field-level collisions. * Note: the unit of work must be used for all updates when using field locking. */ public SelectedFieldsLockingPolicy() { super(); this.lockFieldsByTable = new HashMap(5); this.lockFields = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); } /** * PUBLIC: * Add a fieldname to lock on. All fields in this list will be compared when Updating * if the value of any of the fields does not match the value in memory, an * OptimisticLockException will be thrown. * * Note: An Automatic update will not be done on this field, only a comparison occurs. */ public void addLockFieldName(String fieldName) { getLockFields().addElement(new DatabaseField(fieldName)); } /** * INTERNAL: * Values to be included in the locking mechanism are added to the translation row. * For changed fields the normal build row is ok as only changed fields matter. */ public void addLockValuesToTranslationRow(ObjectLevelModifyQuery query) throws DatabaseException{ Object object; verifyUsage(query.getSession()); if (query.isDeleteObjectQuery()) { object = query.getObject(); } else { object = query.getBackupClone(); } // EL bug 319759 if (query.isUpdateObjectQuery()) { query.setShouldValidateUpdateCallCacheUse(true); } for (Iterator vectors = getLockFieldsByTable().values().iterator(); vectors.hasNext();) { for (Enumeration fields = ((Vector)vectors.next()).elements(); fields.hasMoreElements();) { DatabaseField field = (DatabaseField)fields.nextElement(); DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForField(field); //Bug5892889, Exception will be thrown if no matched database field found if(mapping == null ){ throw DatabaseException.specifiedLockingFieldsNotFoundInDatabase(field.getQualifiedName()); }else{ mapping.writeFromObjectIntoRow(object, query.getTranslationRow(), query.getSession(), WriteType.UNDEFINED); } } } } /** * INTERNAL: * returns the lock fields to compare based on the passed in table. */ protected Vector getFieldsToCompare(org.eclipse.persistence.internal.helper.DatabaseTable table, AbstractRecord transRow, AbstractRecord modifyRow) { return getLockFields(table); } /** * INTERNAL: * Returns the lock fields */ public Vector getLockFields() { return lockFields; } /** * INTERNAL: * returns the lock fields based on the passed in table */ protected Vector getLockFields(DatabaseTable table) { Vector tempVector = (Vector)lockFieldsByTable.get(table); if (tempVector == null) { return new Vector(); } return tempVector; } /** * INTERNAL: * returns the lock fields */ protected Map getLockFieldsByTable() { return lockFieldsByTable; } /** * INTERNAL: * It is responsible for initializing the policy; */ public void initialize(AbstractSession session) { super.initialize(session); List lockFields = getLockFields(); int size = lockFields.size(); for (int index = 0; index < size; index++) { DatabaseField field = (DatabaseField)lockFields.get(index); field = descriptor.buildField(field); lockFields.set(index, field); Vector fieldsForTable = (Vector)getLockFieldsByTable().get(field.getTable()); if (fieldsForTable == null) { fieldsForTable = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(); getLockFieldsByTable().put(field.getTable(), fieldsForTable); } fieldsForTable.addElement(field); } } /** * PUBLIC: * Set the field names to lock on. All fields in this list will be compared when Updating. * If the value of any of the fields does not match the value in memory, an * OptimisticLockException will be thrown. * * Note: An Automatic update will not be done on this field, only a comparison occurs. */ public void setLockFieldNames(Vector lockFieldNames) { for (Enumeration enumtr = lockFieldNames.elements(); enumtr.hasMoreElements();) { addLockFieldName((String)enumtr.nextElement()); } } /** * INTERNAL: * Used to set the field names to be used in this policy. */ public void setLockFields(Map lockFieldsByTable) { this.lockFieldsByTable = lockFieldsByTable; } /** * INTERNAL: * Sets the lock fields */ protected void setLockFields(Vector lockFields) { this.lockFields = lockFields; } /** * INTERNAL: * Used to set the field names to be used in this policy. */ protected void setLockFieldsByTable(Map lockFieldsByTable) { this.lockFieldsByTable = lockFieldsByTable; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy