use of org.hibernate.LockMode in project hibernate-orm by hibernate.
the class QueryLoader method getLockModes.
/**
* @param lockOptions a collection of lock modes specified dynamically via the Query interface
*/
@Override
protected LockMode[] getLockModes(LockOptions lockOptions) {
if (lockOptions == null) {
return defaultLockModes;
}
if (lockOptions.getAliasLockCount() == 0 && (lockOptions.getLockMode() == null || LockMode.NONE.equals(lockOptions.getLockMode()))) {
return defaultLockModes;
}
// unfortunately this stuff can't be cached because
// it is per-invocation, not constant for the
// QueryTranslator instance
LockMode[] lockModesArray = new LockMode[entityAliases.length];
for (int i = 0; i < entityAliases.length; i++) {
LockMode lockMode = lockOptions.getEffectiveLockMode(entityAliases[i]);
if (lockMode == null) {
// NONE, because its the requested lock mode, not the actual!
lockMode = LockMode.NONE;
}
lockModesArray[i] = lockMode;
}
return lockModesArray;
}
use of org.hibernate.LockMode in project hibernate-orm by hibernate.
the class QueryTranslatorImpl method getLockModes.
@Override
protected LockMode[] getLockModes(LockOptions lockOptions) {
// unfortunately this stuff can't be cached because
// it is per-invocation, not constant for the
// QueryTranslator instance
HashMap nameLockOptions = new HashMap();
if (lockOptions == null) {
lockOptions = LockOptions.NONE;
}
if (lockOptions.getAliasLockCount() > 0) {
Iterator iter = lockOptions.getAliasLockIterator();
while (iter.hasNext()) {
Map.Entry me = (Map.Entry) iter.next();
nameLockOptions.put(getAliasName((String) me.getKey()), me.getValue());
}
}
LockMode[] lockModesArray = new LockMode[names.length];
for (int i = 0; i < names.length; i++) {
LockMode lm = (LockMode) nameLockOptions.get(names[i]);
// if ( lm == null ) lm = LockOptions.NONE;
if (lm == null) {
lm = lockOptions.getLockMode();
}
lockModesArray[i] = lm;
}
return lockModesArray;
}
use of org.hibernate.LockMode in project hibernate-orm by hibernate.
the class EntityReferenceInitializerImpl method hydrateEntityState.
@Override
public void hydrateEntityState(ResultSet resultSet, ResultSetProcessingContextImpl context) {
final EntityReferenceProcessingState processingState = context.getProcessingState(entityReference);
// If there is no identifier for this entity reference for this row, nothing to do
if (processingState.isMissingIdentifier()) {
handleMissingIdentifier(context);
return;
}
// make sure we have the EntityKey
final EntityKey entityKey = processingState.getEntityKey();
if (entityKey == null) {
handleMissingIdentifier(context);
return;
}
// Have we already hydrated this entity's state?
if (processingState.getEntityInstance() != null) {
return;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// In getting here, we know that:
// 1) We need to hydrate the entity state
// 2) We have a valid EntityKey for the entity
// see if we have an existing entry in the session for this EntityKey
final Object existing = context.getSession().getEntityUsingInterceptor(entityKey);
if (existing != null) {
// It is previously associated with the Session, perform some checks
if (!entityReference.getEntityPersister().isInstance(existing)) {
throw new WrongClassException("loaded object was of wrong class " + existing.getClass(), entityKey.getIdentifier(), entityReference.getEntityPersister().getEntityName());
}
checkVersion(resultSet, context, entityKey, existing);
// use the existing association as the hydrated state
processingState.registerEntityInstance(existing);
// context.registerHydratedEntity( entityReference, entityKey, existing );
return;
}
// Otherwise, we need to load it from the ResultSet...
// determine which entity instance to use. Either the supplied one, or instantiate one
Object entityInstance = null;
if (isReturn && context.shouldUseOptionalEntityInformation() && context.getQueryParameters().getOptionalObject() != null) {
final EntityKey optionalEntityKey = ResultSetProcessorHelper.getOptionalObjectKey(context.getQueryParameters(), context.getSession());
if (optionalEntityKey != null && optionalEntityKey.equals(entityKey)) {
entityInstance = context.getQueryParameters().getOptionalObject();
}
}
final String concreteEntityTypeName = getConcreteEntityTypeName(resultSet, context, entityKey);
if (entityInstance == null) {
entityInstance = context.getSession().instantiate(concreteEntityTypeName, entityKey.getIdentifier());
}
processingState.registerEntityInstance(entityInstance);
// need to hydrate it.
// grab its state from the ResultSet and keep it in the Session
// (but don't yet initialize the object itself)
// note that we acquire LockMode.READ even if it was not requested
log.trace("hydrating entity state");
final LockMode requestedLockMode = context.resolveLockMode(entityReference);
final LockMode lockModeToAcquire = requestedLockMode == LockMode.NONE ? LockMode.READ : requestedLockMode;
loadFromResultSet(resultSet, context, entityInstance, concreteEntityTypeName, entityKey, lockModeToAcquire);
}
use of org.hibernate.LockMode in project hibernate-orm by hibernate.
the class EntityReferenceInitializerImpl method checkVersion.
private void checkVersion(ResultSet resultSet, ResultSetProcessingContext context, EntityKey entityKey, Object existing) {
final LockMode requestedLockMode = context.resolveLockMode(entityReference);
if (requestedLockMode != LockMode.NONE) {
final LockMode currentLockMode = context.getSession().getPersistenceContext().getEntry(existing).getLockMode();
final boolean isVersionCheckNeeded = entityReference.getEntityPersister().isVersioned() && currentLockMode.lessThan(requestedLockMode);
// by a re-entrant load (re-entrant loads *always* have lock mode NONE)
if (isVersionCheckNeeded) {
// we only check the version when *upgrading* lock modes
checkVersion(context.getSession(), resultSet, entityReference.getEntityPersister(), entityReferenceAliases.getColumnAliases(), entityKey, existing);
// we need to upgrade the lock mode to the mode requested
context.getSession().getPersistenceContext().getEntry(existing).setLockMode(requestedLockMode);
}
}
}
use of org.hibernate.LockMode in project hibernate-orm by hibernate.
the class AbstractLockUpgradeEventListener method upgradeLock.
/**
* Performs a pessimistic lock upgrade on a given entity, if needed.
*
* @param object The entity for which to upgrade the lock.
* @param entry The entity's EntityEntry instance.
* @param lockOptions contains the requested lock mode.
* @param source The session which is the source of the event being processed.
*/
protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOptions, EventSource source) {
LockMode requestedLockMode = lockOptions.getLockMode();
if (requestedLockMode.greaterThan(entry.getLockMode())) {
if (entry.getStatus() != Status.MANAGED) {
throw new ObjectDeletedException("attempted to lock a deleted instance", entry.getId(), entry.getPersister().getEntityName());
}
final EntityPersister persister = entry.getPersister();
if (log.isTraceEnabled()) {
log.tracev("Locking {0} in mode: {1}", MessageHelper.infoString(persister, entry.getId(), source.getFactory()), requestedLockMode);
}
final boolean cachingEnabled = persister.canWriteToCache();
SoftLock lock = null;
Object ck = null;
try {
if (cachingEnabled) {
EntityDataAccess cache = persister.getCacheAccessStrategy();
ck = cache.generateCacheKey(entry.getId(), persister, source.getFactory(), source.getTenantIdentifier());
lock = cache.lockItem(source, ck, entry.getVersion());
}
if (persister.isVersioned() && requestedLockMode == LockMode.FORCE) {
// todo : should we check the current isolation mode explicitly?
Object nextVersion = persister.forceVersionIncrement(entry.getId(), entry.getVersion(), source);
entry.forceLocked(object, nextVersion);
} else {
persister.lock(entry.getId(), entry.getVersion(), object, lockOptions, source);
}
entry.setLockMode(requestedLockMode);
} finally {
// so release the soft lock
if (cachingEnabled) {
persister.getCacheAccessStrategy().unlockItem(source, ck, lock);
}
}
}
}
Aggregations