protected String applyLocks(
String sql,
QueryParameters parameters,
Dialect dialect,
List<AfterLoadAction> afterLoadActions) throws QueryException {
final LockOptions lockOptions = parameters.getLockOptions();
if ( lockOptions == null ||
( lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0 ) ) {
return sql;
}
if ( dialect.useFollowOnLocking() ) {
final LockMode lockMode = determineFollowOnLockMode( lockOptions );
if( lockMode != LockMode.UPGRADE_SKIPLOCKED ) {
// Dialect prefers to perform locking in a separate step
LOG.usingFollowOnLocking();
final LockOptions lockOptionsToUse = new LockOptions( lockMode );
lockOptionsToUse.setTimeOut( lockOptions.getTimeOut() );
lockOptionsToUse.setScope( lockOptions.getScope() );
afterLoadActions.add(
new AfterLoadAction() {
@Override
public void afterLoad(SessionImplementor session, Object entity, Loadable persister) {
( (Session) session ).buildLockRequest( lockOptionsToUse )
.lock( persister.getEntityName(), entity );
}
}
);
parameters.setLockOptions( new LockOptions() );
return sql;
}
}
final LockOptions locks = new LockOptions(lockOptions.getLockMode());
locks.setScope( lockOptions.getScope());
locks.setTimeOut( lockOptions.getTimeOut());
final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null;
final String[] drivingSqlAliases = getAliases();
for ( int i = 0; i < drivingSqlAliases.length; i++ ) {
final LockMode lockMode = lockOptions.getAliasSpecificLockMode( drivingSqlAliases[i] );
if ( lockMode != null ) {
final Lockable drivingPersister = ( Lockable ) getEntityPersisters()[i];
final String rootSqlAlias = drivingPersister.getRootTableAlias( drivingSqlAliases[i] );
locks.setAliasSpecificLockMode( rootSqlAlias, lockMode );
if ( keyColumnNames != null ) {
keyColumnNames.put( rootSqlAlias, drivingPersister.getRootTableIdentifierColumnNames() );
}
}
}