private Query applyProperties(Query query) {
   if (lockOptions.getLockMode() != LockMode.NONE) {
     query.setLockMode(getLockMode(lockOptions.getLockMode()));
   }
   Object queryTimeout;
   if ((queryTimeout = getProperties().get(QueryHints.SPEC_HINT_TIMEOUT)) != null) {
     query.setHint(QueryHints.SPEC_HINT_TIMEOUT, queryTimeout);
   }
   return query;
 }
  @Override
  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;
    }

    // user is request locking, lets see if we can apply locking directly to the SQL...

    // 		some dialects wont allow locking with paging...
    afterLoadActions.add(
        new AfterLoadAction() {
          private final LockOptions originalLockOptions = lockOptions.makeCopy();

          @Override
          public void afterLoad(SessionImplementor session, Object entity, Loadable persister) {
            ((Session) session)
                .buildLockRequest(originalLockOptions)
                .lock(persister.getEntityName(), entity);
          }
        });
    parameters.getLockOptions().setLockMode(LockMode.READ);

    return sql;
  }
  @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;
  }
  protected void initPersisters(
      final List associations,
      final LockOptions lockOptions,
      final AssociationInitCallback callback)
      throws MappingException {
    final int joins = countEntityPersisters(associations);
    final int collections = countCollectionPersisters(associations);

    collectionOwners = collections == 0 ? null : new int[collections];
    collectionPersisters = collections == 0 ? null : new CollectionPersister[collections];
    collectionSuffixes = BasicLoader.generateSuffixes(joins + 1, collections);

    this.lockOptions = lockOptions;

    persisters = new Loadable[joins];
    aliases = new String[joins];
    owners = new int[joins];
    ownerAssociationTypes = new EntityType[joins];
    lockModeArray = ArrayHelper.fillArray(lockOptions.getLockMode(), joins);

    int i = 0;
    int j = 0;
    Iterator iter = associations.iterator();
    while (iter.hasNext()) {
      final OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
      if (!oj.isCollection()) {

        persisters[i] = (Loadable) oj.getJoinable();
        aliases[i] = oj.getRHSAlias();
        owners[i] = oj.getOwner(associations);
        ownerAssociationTypes[i] = (EntityType) oj.getJoinableType();
        callback.associationProcessed(oj, i);
        i++;

      } else {

        QueryableCollection collPersister = (QueryableCollection) oj.getJoinable();
        if (oj.getJoinType() == JoinType.LEFT_OUTER_JOIN && !oj.hasRestriction()) {
          // it must be a collection fetch
          collectionPersisters[j] = collPersister;
          collectionOwners[j] = oj.getOwner(associations);
          j++;
        }

        if (collPersister.isOneToMany()) {
          persisters[i] = (Loadable) collPersister.getElementPersister();
          aliases[i] = oj.getRHSAlias();
          callback.associationProcessed(oj, i);
          i++;
        }
      }
    }

    if (ArrayHelper.isAllNegative(owners)) owners = null;
    if (collectionOwners != null && ArrayHelper.isAllNegative(collectionOwners)) {
      collectionOwners = null;
    }
  }
 @Override
 protected String applyLocks(
     String sql,
     QueryParameters parameters,
     Dialect dialect,
     List<AfterLoadAction> afterLoadActions)
     throws QueryException {
   // can't cache this stuff either (per-invocation)
   final LockOptions lockOptions = parameters.getLockOptions();
   final String result;
   if (lockOptions == null
       || (lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0)) {
     return sql;
   } else {
     LockOptions locks = new LockOptions();
     locks.setLockMode(lockOptions.getLockMode());
     locks.setTimeOut(lockOptions.getTimeOut());
     locks.setScope(lockOptions.getScope());
     Iterator iter = lockOptions.getAliasLockIterator();
     while (iter.hasNext()) {
       Map.Entry me = (Map.Entry) iter.next();
       locks.setAliasSpecificLockMode(
           getAliasName((String) me.getKey()), (LockMode) me.getValue());
     }
     Map keyColumnNames = null;
     if (dialect.forUpdateOfColumns()) {
       keyColumnNames = new HashMap();
       for (int i = 0; i < names.length; i++) {
         keyColumnNames.put(names[i], persisters[i].getIdentifierColumnNames());
       }
     }
     result = dialect.applyLocksToSql(sql, locks, keyColumnNames);
   }
   logQuery(queryString, result);
   return result;
 }
 @Override
 public String appendLockHint(LockOptions lockOptions, String tableName) {
   return lockOptions.getLockMode().greaterThan(LockMode.READ)
       ? tableName + " holdlock"
       : tableName;
 }
 /**
  * @see EntityPersister#load(Serializable, Object, org.hibernate.LockOptions , SessionImplementor)
  */
 public Object load(
     Serializable id, Object optionalObject, LockOptions lockOptions, SessionImplementor session)
     throws HibernateException {
   return load(id, optionalObject, lockOptions.getLockMode(), session);
 }