/** * PUBLIC: * Set the locking policy to use timestamp version locking. * This updates the timestamp field on all updates, first comparing that the field has not changed to detect locking conflicts. * Note: many database have limited precision of timestamps which can be an issue is highly concurrent systems. * * The parameter 'shouldStoreInCache' configures the version lock value to be stored in the cache or in the object. * Note: if using a stateless model where the object can be passed to a client and then later updated in a different transaction context, * then the version lock value should not be stored in the cache, but in the object to ensure it is the correct value for that object. * @see VersionLockingPolicy */ public void useTimestampLocking(String writeLockFieldName, boolean shouldStoreInCache) { TimestampLockingPolicy policy = new TimestampLockingPolicy(writeLockFieldName); if (shouldStoreInCache) { policy.storeInCache(); } else { policy.storeInObject(); } setOptimisticLockingPolicy(policy); }
/** * INTERNAL: * Compares the value with the value from the object (or cache). * Will return true if the currentValue is newer than the domainObject. */ public boolean isNewerVersion(Object currentValue, Object domainObject, java.util.Vector primaryKey, AbstractSession session) { java.sql.Timestamp writeLockFieldValue; java.sql.Timestamp newWriteLockFieldValue = (java.sql.Timestamp)currentValue; if (isStoredInCache()) { writeLockFieldValue = (java.sql.Timestamp)session.getIdentityMapAccessorInstance().getWriteLockValue(primaryKey, domainObject.getClass(), getDescriptor()); } else { writeLockFieldValue = (java.sql.Timestamp)lockValueFromObject(domainObject); } return isNewerVersion(newWriteLockFieldValue, writeLockFieldValue); }
/** * INTERNAL: * Returns the new Timestamp value. */ public Object getNewLockValue(ModifyQuery query) { return getInitialWriteValue(query.getSession()); }
/** * PUBLIC: * Set if policy uses server time. */ public void setUsesServerTime(boolean usesServerTime) { if (usesServerTime) { useServerTime(); } else { useLocalTime(); } }
/** * INTERNAL: * This method will return the optimistic lock value for the object */ public Object getWriteLockValue(Object domainObject, java.util.Vector primaryKey, AbstractSession session) { java.sql.Timestamp writeLockFieldValue = null; if (isStoredInCache()) { writeLockFieldValue = (java.sql.Timestamp)session.getIdentityMapAccessorInstance().getWriteLockValue(primaryKey, domainObject.getClass(), getDescriptor()); } else { //CR#2281 notStoredInCache prevent ClassCastException Object lockValue = lockValueFromObject(domainObject); if (lockValue != null) { if (lockValue instanceof java.sql.Timestamp) { writeLockFieldValue = (java.sql.Timestamp)lockValueFromObject(domainObject); } else { throw OptimisticLockException.needToMapJavaSqlTimestampWhenStoredInObject(); } } } return writeLockFieldValue; }
/** * INTERNAL: * returns the initial locking value */ protected Object getInitialWriteValue(AbstractSession session) { if (usesLocalTime()) { return new Timestamp(System.currentTimeMillis()); } if (usesServerTime()) { AbstractSession readSession = session.getSessionForClass(getDescriptor().getJavaClass()); while (readSession.isUnitOfWork()) { readSession = ((UnitOfWorkImpl)readSession).getParent().getSessionForClass(getDescriptor().getJavaClass()); } return readSession.getDatasourceLogin().getDatasourcePlatform().getTimestampFromServer(session, readSession.getName()); } return null; }
/** * INTERNAL: * Return the value that should be stored in the identity map. If the value * is stored in the object, then return a null. */ public Object getValueToPutInCache(AbstractRecord row, AbstractSession session) { if (isStoredInCache()) { return session.getDatasourcePlatform().convertObject(row.get(getWriteLockField()), ClassConstants.TIMESTAMP); } else { return null; } }
/** * INTERNAL: * Process a version accessor. */ @Override public void process() { // This will initialize the m_field variable. Accessible through getField(). super.process(); // Process an @Version or version element if there is one. if (getDescriptor().usesOptimisticLocking()) { // Ignore the version locking if it is already set. getLogger().logConfigMessage(MetadataLogger.IGNORE_VERSION_LOCKING, this); } else { MetadataClass lockType = getRawClass(); getDatabaseField().setTypeName(getJavaClassName(lockType)); if (isValidVersionLockingType(lockType) || isValidTimestampVersionLockingType(lockType)) { for (MetadataDescriptor owningDescriptor : getOwningDescriptors()) { VersionLockingPolicy policy = isValidVersionLockingType(lockType) ? new VersionLockingPolicy(getDatabaseField()) : new TimestampLockingPolicy(getDatabaseField()); policy.storeInObject(); policy.setIsCascaded(getDescriptor().usesCascadedOptimisticLocking()); owningDescriptor.setOptimisticLockingPolicy(policy); } } else { throw ValidationException.invalidTypeForVersionAttribute(getAttributeName(), lockType, getJavaClass()); } } } }
/** * INTERNAL: * This method will return the optimistic lock value for the object. */ @Override public Object getWriteLockValue(Object domainObject, Object primaryKey, AbstractSession session) { java.sql.Timestamp writeLockFieldValue = null; if (isStoredInCache()) { writeLockFieldValue = (java.sql.Timestamp)session.getIdentityMapAccessorInstance().getWriteLockValue(primaryKey, domainObject.getClass(), getDescriptor()); } else { //CR#2281 notStoredInCache prevent ClassCastException Object lockValue = lockValueFromObject(domainObject); if (lockValue != null) { if (lockValue instanceof java.sql.Timestamp) { writeLockFieldValue = (java.sql.Timestamp)lockValueFromObject(domainObject); } else { throw OptimisticLockException.needToMapJavaSqlTimestampWhenStoredInObject(); } } } return writeLockFieldValue; }
/** * INTERNAL: * returns the initial locking value */ protected Object getInitialWriteValue(AbstractSession session) { if (usesLocalTime()) { return new Timestamp(System.currentTimeMillis()); } if (usesServerTime()) { AbstractSession readSession = session.getSessionForClass(getDescriptor().getJavaClass()); while (readSession.isUnitOfWork()) { readSession = ((UnitOfWorkImpl)readSession).getParent().getSessionForClass(getDescriptor().getJavaClass()); } return readSession.getDatasourceLogin().getDatasourcePlatform().getTimestampFromServer(session, readSession.getName()); } return null; }
/** * PUBLIC: * Set if policy uses server time. */ public void setUsesServerTime(boolean usesServerTime) { if (usesServerTime) { useServerTime(); } else { useLocalTime(); } }
/** * INTERNAL: * Return the value that should be stored in the identity map. If the value * is stored in the object, then return a null. */ public Object getValueToPutInCache(AbstractRecord row, AbstractSession session) { if (isStoredInCache()) { return session.getDatasourcePlatform().convertObject(row.get(getWriteLockField()), ClassConstants.TIMESTAMP); } else { return null; } }
/** * INTERNAL: * Compares the value with the value from the object (or cache). * Will return true if the currentValue is newer than the domainObject. */ @Override public boolean isNewerVersion(Object currentValue, Object domainObject, Object primaryKey, AbstractSession session) { java.sql.Timestamp writeLockFieldValue; java.sql.Timestamp newWriteLockFieldValue = (java.sql.Timestamp)currentValue; if (isStoredInCache()) { writeLockFieldValue = (java.sql.Timestamp)session.getIdentityMapAccessorInstance().getWriteLockValue(primaryKey, domainObject.getClass(), getDescriptor()); } else { writeLockFieldValue = (java.sql.Timestamp)lockValueFromObject(domainObject); } return isNewerVersion(newWriteLockFieldValue, writeLockFieldValue); }
/** * INTERNAL: * This method will return the optimistic lock value for the object. */ @Override public Object getWriteLockValue(Object domainObject, Object primaryKey, AbstractSession session) { java.sql.Timestamp writeLockFieldValue = null; if (isStoredInCache()) { writeLockFieldValue = (java.sql.Timestamp)session.getIdentityMapAccessorInstance().getWriteLockValue(primaryKey, domainObject.getClass(), getDescriptor()); } else { //CR#2281 notStoredInCache prevent ClassCastException Object lockValue = lockValueFromObject(domainObject); if (lockValue != null) { if (lockValue instanceof java.sql.Timestamp) { writeLockFieldValue = (java.sql.Timestamp)lockValueFromObject(domainObject); } else { throw OptimisticLockException.needToMapJavaSqlTimestampWhenStoredInObject(); } } } return writeLockFieldValue; }
/** * PUBLIC: * Set the locking policy to use timestamp version locking. * This updates the timestamp field on all updates, first comparing that the field has not changed to detect locking conflicts. * Note: many database have limited precision of timestamps which can be an issue is highly concurrent systems. * * The parameter 'shouldStoreInCache' configures the version lock value to be stored in the cache or in the object. * Note: if using a stateless model where the object can be passed to a client and then later updated in a different transaction context, * then the version lock value should not be stored in the cache, but in the object to ensure it is the correct value for that object. * @see VersionLockingPolicy */ public void useTimestampLocking(String writeLockFieldName, boolean shouldStoreInCache) { TimestampLockingPolicy policy = new TimestampLockingPolicy(writeLockFieldName); if (shouldStoreInCache) { policy.storeInCache(); } else { policy.storeInObject(); } setOptimisticLockingPolicy(policy); }
/** * INTERNAL: * returns the initial locking value */ protected Object getInitialWriteValue(AbstractSession session) { if (usesLocalTime()) { return new Timestamp(System.currentTimeMillis()); } if (usesServerTime()) { AbstractSession readSession = session.getSessionForClass(getDescriptor().getJavaClass()); while (readSession.isUnitOfWork()) { readSession = ((UnitOfWorkImpl)readSession).getParent().getSessionForClass(getDescriptor().getJavaClass()); } return readSession.getDatasourceLogin().getDatasourcePlatform().getTimestampFromServer(session, readSession.getName()); } return null; }
/** * PUBLIC: * Set if policy uses server time. */ public void setUsesServerTime(boolean usesServerTime) { if (usesServerTime) { useServerTime(); } else { useLocalTime(); } }
/** * INTERNAL: * Return the value that should be stored in the identity map. If the value * is stored in the object, then return a null. */ public Object getValueToPutInCache(AbstractRecord row, AbstractSession session) { if (isStoredInCache()) { return session.getDatasourcePlatform().convertObject(row.get(getWriteLockField()), ClassConstants.TIMESTAMP); } else { return null; } }
/** * INTERNAL: * Returns the new Timestamp value. */ public Object getNewLockValue(ModifyQuery query) { return getInitialWriteValue(query.getSession()); }
/** * INTERNAL: * Compares the value with the value from the object (or cache). * Will return true if the currentValue is newer than the domainObject. */ @Override public boolean isNewerVersion(Object currentValue, Object domainObject, Object primaryKey, AbstractSession session) { java.sql.Timestamp writeLockFieldValue; java.sql.Timestamp newWriteLockFieldValue = (java.sql.Timestamp)currentValue; if (isStoredInCache()) { writeLockFieldValue = (java.sql.Timestamp)session.getIdentityMapAccessorInstance().getWriteLockValue(primaryKey, domainObject.getClass(), getDescriptor()); } else { writeLockFieldValue = (java.sql.Timestamp)lockValueFromObject(domainObject); } return isNewerVersion(newWriteLockFieldValue, writeLockFieldValue); }