@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 PersistenceException wrapLockException(HibernateException e, LockOptions lockOptions) {
   final PersistenceException pe;
   if (e instanceof OptimisticEntityLockException) {
     final OptimisticEntityLockException lockException = (OptimisticEntityLockException) e;
     pe =
         new OptimisticLockException(
             lockException.getMessage(), lockException, lockException.getEntity());
   } else if (e instanceof org.hibernate.exception.LockTimeoutException) {
     pe = new LockTimeoutException(e.getMessage(), e, null);
   } else if (e instanceof PessimisticEntityLockException) {
     final PessimisticEntityLockException lockException = (PessimisticEntityLockException) e;
     if (lockOptions != null && lockOptions.getTimeOut() > -1) {
       // assume lock timeout occurred if a timeout or NO WAIT was specified
       pe =
           new LockTimeoutException(
               lockException.getMessage(), lockException, lockException.getEntity());
     } else {
       pe =
           new PessimisticLockException(
               lockException.getMessage(), lockException, lockException.getEntity());
     }
   } else if (e instanceof org.hibernate.PessimisticLockException) {
     final org.hibernate.PessimisticLockException jdbcLockException =
         (org.hibernate.PessimisticLockException) e;
     if (lockOptions != null && lockOptions.getTimeOut() > -1) {
       // assume lock timeout occurred if a timeout or NO WAIT was specified
       pe = new LockTimeoutException(jdbcLockException.getMessage(), jdbcLockException, null);
     } else {
       pe = new PessimisticLockException(jdbcLockException.getMessage(), jdbcLockException, null);
     }
   } else {
     pe = new OptimisticLockException(e);
   }
   return pe;
 }
  public QueryParameters getQueryParameters() {
    LockOptions lockOptions = new LockOptions();
    RowSelection selection = new RowSelection();
    selection.setFirstRow(rootCriteria.getFirstResult());
    selection.setMaxRows(rootCriteria.getMaxResults());
    selection.setTimeout(rootCriteria.getTimeout());
    selection.setFetchSize(rootCriteria.getFetchSize());
    final Map<String, LockMode> lockModeMap = rootCriteria.getLockModes();
    for (final String key : lockModeMap.keySet()) {
      final Criteria subcriteria = getAliasedCriteria(key);
      lockOptions.setAliasSpecificLockMode(getSQLAlias(subcriteria), lockModeMap.get(key));
    }
    final List<Object> values = new ArrayList<Object>();
    final List<Type> types = new ArrayList<Type>();
    final Iterator<CriteriaImpl.Subcriteria> subcriteriaIterator =
        rootCriteria.iterateSubcriteria();
    while (subcriteriaIterator.hasNext()) {
      CriteriaImpl.Subcriteria subcriteria = subcriteriaIterator.next();
      LockMode lm = subcriteria.getLockMode();
      if (lm != null) {
        lockOptions.setAliasSpecificLockMode(getSQLAlias(subcriteria), lm);
      }
      if (subcriteria.getWithClause() != null) {
        TypedValue[] tv = subcriteria.getWithClause().getTypedValues(subcriteria, this);
        for (TypedValue aTv : tv) {
          values.add(aTv.getValue());
          types.add(aTv.getType());
        }
      }
    }

    // Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering,
    // because the lock mode gathering loop now contains join clauses which can contain
    // parameter bindings (as in the HQL WITH clause).
    Iterator<CriteriaImpl.CriterionEntry> iter = rootCriteria.iterateExpressionEntries();
    while (iter.hasNext()) {
      CriteriaImpl.CriterionEntry ce = iter.next();
      TypedValue[] tv = ce.getCriterion().getTypedValues(ce.getCriteria(), this);
      for (TypedValue aTv : tv) {
        values.add(aTv.getValue());
        types.add(aTv.getType());
      }
    }

    Object[] valueArray = values.toArray();
    Type[] typeArray = ArrayHelper.toTypeArray(types);
    return new QueryParameters(
        typeArray,
        valueArray,
        lockOptions,
        selection,
        rootCriteria.isReadOnlyInitialized(),
        (rootCriteria.isReadOnlyInitialized() && rootCriteria.isReadOnly()),
        rootCriteria.getCacheable(),
        rootCriteria.getCacheRegion(),
        rootCriteria.getComment(),
        rootCriteria.getQueryHints(),
        rootCriteria.isLookupByNaturalKey(),
        rootCriteria.getResultTransformer());
  }
  public QueryParameters getQueryParameters() {
    LockOptions lockOptions = new LockOptions();
    RowSelection selection = new RowSelection();
    selection.setFirstRow(rootCriteria.getFirstResult());
    selection.setMaxRows(rootCriteria.getMaxResults());
    selection.setTimeout(rootCriteria.getTimeout());
    selection.setFetchSize(rootCriteria.getFetchSize());

    Iterator iter = rootCriteria.getLockModes().entrySet().iterator();
    while (iter.hasNext()) {
      Map.Entry me = (Map.Entry) iter.next();
      final Criteria subcriteria = getAliasedCriteria((String) me.getKey());
      lockOptions.setAliasSpecificLockMode(getSQLAlias(subcriteria), (LockMode) me.getValue());
    }
    List values = new ArrayList();
    List types = new ArrayList();
    iter = rootCriteria.iterateSubcriteria();
    while (iter.hasNext()) {
      CriteriaImpl.Subcriteria subcriteria = (CriteriaImpl.Subcriteria) iter.next();
      LockMode lm = subcriteria.getLockMode();
      if (lm != null) {
        lockOptions.setAliasSpecificLockMode(getSQLAlias(subcriteria), lm);
      }
      if (subcriteria.getWithClause() != null) {
        TypedValue[] tv = subcriteria.getWithClause().getTypedValues(subcriteria, this);
        for (int i = 0; i < tv.length; i++) {
          values.add(tv[i].getValue());
          types.add(tv[i].getType());
        }
      }
    }

    // Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering,
    // because the lock mode gathering loop now contains join clauses which can contain
    // parameter bindings (as in the HQL WITH clause).
    iter = rootCriteria.iterateExpressionEntries();
    while (iter.hasNext()) {
      CriteriaImpl.CriterionEntry ce = (CriteriaImpl.CriterionEntry) iter.next();
      TypedValue[] tv = ce.getCriterion().getTypedValues(ce.getCriteria(), this);
      for (int i = 0; i < tv.length; i++) {
        values.add(tv[i].getValue());
        types.add(tv[i].getType());
      }
    }

    Object[] valueArray = values.toArray();
    Type[] typeArray = ArrayHelper.toTypeArray(types);
    return new QueryParameters(
        typeArray,
        valueArray,
        lockOptions,
        selection,
        rootCriteria.isReadOnlyInitialized(),
        (rootCriteria.isReadOnlyInitialized() ? rootCriteria.isReadOnly() : false),
        rootCriteria.getCacheable(),
        rootCriteria.getCacheRegion(),
        rootCriteria.getComment(),
        rootCriteria.isLookupByNaturalKey(),
        rootCriteria.getResultTransformer());
  }
 public LockOptions getLockRequest(LockModeType lockModeType, Map<String, Object> properties) {
   LockOptions lockOptions = new LockOptions();
   LockOptions.copy(this.lockOptions, lockOptions);
   lockOptions.setLockMode(getLockMode(lockModeType));
   if (properties != null) {
     setLockOptions(properties, lockOptions);
   }
   return lockOptions;
 }
 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;
 }
  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;
    }
  }
 /*  77:    */
 /*  78:    */ protected String generateLockString(int lockTimeout) /*  79:    */ {
   /*  80:122 */ SessionFactoryImplementor factory = getLockable().getFactory();
   /*  81:123 */ LockOptions lockOptions = new LockOptions(getLockMode());
   /*  82:124 */ lockOptions.setTimeOut(lockTimeout);
   /*  83:125 */ SimpleSelect select =
       new SimpleSelect(factory.getDialect())
           .setLockOptions(lockOptions)
           .setTableName(getLockable().getRootTableName())
           .addColumn(getLockable().getRootTableIdentifierColumnNames()[0])
           .addCondition(getLockable().getRootTableIdentifierColumnNames(), "=?");
   /*  84:130 */ if (getLockable().isVersioned()) {
     /*  85:131 */ select.addCondition(getLockable().getVersionColumnName(), "=?");
     /*  86:    */ }
   /*  87:133 */ if (factory.getSettings().isCommentsEnabled()) {
     /*  88:134 */ select.setComment(getLockMode() + " lock " + getLockable().getEntityName());
     /*  89:    */ }
   /*  90:136 */ return select.toStatementString();
   /*  91:    */ }
 protected String generateLockString(int lockTimeout) {
   SessionFactoryImplementor factory = getLockable().getFactory();
   LockOptions lockOptions = new LockOptions(getLockMode());
   lockOptions.setTimeOut(lockTimeout);
   SimpleSelect select =
       new SimpleSelect(factory.getDialect())
           .setLockOptions(lockOptions)
           .setTableName(getLockable().getRootTableName())
           .addColumn(getLockable().getRootTableIdentifierColumnNames()[0])
           .addCondition(getLockable().getRootTableIdentifierColumnNames(), "=?");
   if (getLockable().isVersioned()) {
     select.addCondition(getLockable().getVersionColumnName(), "=?");
   }
   if (factory.getSettings().isCommentsEnabled()) {
     select.setComment(getLockMode() + " lock " + getLockable().getEntityName());
   }
   return select.toStatementString();
 }
  private void setLockOptions(Map<String, Object> props, LockOptions options) {
    Object lockScope = props.get(AvailableSettings.LOCK_SCOPE);
    if (lockScope instanceof String
        && PessimisticLockScope.valueOf((String) lockScope) == PessimisticLockScope.EXTENDED) {
      options.setScope(true);
    } else if (lockScope instanceof PessimisticLockScope) {
      boolean extended = PessimisticLockScope.EXTENDED.equals((PessimisticLockScope) lockScope);
      options.setScope(extended);
    } else if (lockScope != null) {
      throw new PersistenceException(
          "Unable to parse " + AvailableSettings.LOCK_SCOPE + ": " + lockScope);
    }

    Object lockTimeout = props.get(AvailableSettings.LOCK_TIMEOUT);
    int timeout = 0;
    boolean timeoutSet = false;
    if (lockTimeout instanceof String) {
      timeout = Integer.parseInt((String) lockTimeout);
      timeoutSet = true;
    } else if (lockTimeout instanceof Number) {
      timeout = ((Number) lockTimeout).intValue();
      timeoutSet = true;
    } else if (lockTimeout != null) {
      throw new PersistenceException(
          "Unable to parse " + AvailableSettings.LOCK_TIMEOUT + ": " + lockTimeout);
    }
    if (timeoutSet) {
      if (timeout < 0) {
        options.setTimeOut(LockOptions.WAIT_FOREVER);
      } else if (timeout == 0) {
        options.setTimeOut(LockOptions.NO_WAIT);
      } else {
        options.setTimeOut(timeout);
      }
    }
  }
 public PersistenceException wrapLockException(HibernateException e, LockOptions lockOptions) {
   PersistenceException pe;
   if (e instanceof org.hibernate.OptimisticLockException) {
     org.hibernate.OptimisticLockException ole = (org.hibernate.OptimisticLockException) e;
     pe = new OptimisticLockException(ole.getMessage(), ole, ole.getEntity());
   } else if (e instanceof org.hibernate.PessimisticLockException) {
     org.hibernate.PessimisticLockException ple = (org.hibernate.PessimisticLockException) e;
     if (lockOptions != null && lockOptions.getTimeOut() > -1) {
       // assume lock timeout occurred if a timeout or NO WAIT was specified
       pe = new LockTimeoutException(ple.getMessage(), ple, ple.getEntity());
     } else {
       pe = new PessimisticLockException(ple.getMessage(), ple, ple.getEntity());
     }
   } else {
     pe = new OptimisticLockException(e);
   }
   return pe;
 }
  @Override
  public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) {
    // TODO:  merge additional lockoptions support in Dialect.applyLocksToSql
    final Iterator itr = aliasedLockOptions.getAliasLockIterator();
    final StringBuilder buffer = new StringBuilder(sql);
    int correction = 0;
    while (itr.hasNext()) {
      final Map.Entry entry = (Map.Entry) itr.next();
      final LockMode lockMode = (LockMode) entry.getValue();
      if (lockMode.greaterThan(LockMode.READ)) {
        final String alias = (String) entry.getKey();
        int start = -1;
        int end = -1;
        if (sql.endsWith(" " + alias)) {
          start = (sql.length() - alias.length()) + correction;
          end = start + alias.length();
        } else {
          int position = sql.indexOf(" " + alias + " ");
          if (position <= -1) {
            position = sql.indexOf(" " + alias + ",");
          }
          if (position > -1) {
            start = position + correction + 1;
            end = start + alias.length();
          }
        }

        if (start > -1) {
          final String lockHint = appendLockHint(lockMode, alias);
          buffer.replace(start, end, lockHint);
          correction += (lockHint.length() - alias.length());
        }
      }
    }
    return buffer.toString();
  }
 @Override
 public String appendLockHint(LockOptions lockOptions, String tableName) {
   return lockOptions.getLockMode().greaterThan(LockMode.READ)
       ? tableName + " holdlock"
       : tableName;
 }
 @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;
 }
 /**
  * @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);
 }