Search in sources :

Example 1 with Lockable

use of org.hibernate.persister.entity.Lockable in project hibernate-orm by hibernate.

the class CriteriaLoader method applyLocks.

@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 || (lockOptions.getAliasLockCount() == 1 && lockOptions.getAliasSpecificLockMode("this_") == LockMode.NONE)))) {
        return sql;
    }
    if ((parameters.getLockOptions().getFollowOnLocking() == null && dialect.useFollowOnLocking(parameters)) || (parameters.getLockOptions().getFollowOnLocking() != null && parameters.getLockOptions().getFollowOnLocking())) {
        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(SharedSessionContractImplementor 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<String, String[]> 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());
            }
        }
    }
    return dialect.applyLocksToSql(sql, locks, keyColumnNames);
}
Also used : OuterJoinLoadable(org.hibernate.persister.entity.OuterJoinLoadable) Loadable(org.hibernate.persister.entity.Loadable) LockOptions(org.hibernate.LockOptions) HashMap(java.util.HashMap) AfterLoadAction(org.hibernate.loader.spi.AfterLoadAction) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) LockMode(org.hibernate.LockMode) Lockable(org.hibernate.persister.entity.Lockable) Session(org.hibernate.Session)

Example 2 with Lockable

use of org.hibernate.persister.entity.Lockable in project hibernate-orm by hibernate.

the class QueryLoader method applyLocks.

@Override
protected String applyLocks(String sql, QueryParameters parameters, Dialect dialect, List<AfterLoadAction> afterLoadActions) throws QueryException {
    // can't cache this stuff either (per-invocation)
    // we are given a map of user-alias -> lock mode
    // create a new map of sql-alias -> lock mode
    final LockOptions lockOptions = parameters.getLockOptions();
    if (lockOptions == null || (lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0)) {
        return sql;
    }
    // 		some dialects wont allow locking with paging...
    if (shouldUseFollowOnLocking(parameters, dialect, afterLoadActions)) {
        return sql;
    }
    //		there are other conditions we might want to add here, such as checking the result types etc
    //		but those are better served afterQuery we have redone the SQL generation to use ASTs.
    // we need both the set of locks and the columns to reference in locks
    // as the ultimate output of this section...
    final LockOptions locks = new LockOptions(lockOptions.getLockMode());
    final Map<String, String[]> keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap<>() : null;
    locks.setScope(lockOptions.getScope());
    locks.setTimeOut(lockOptions.getTimeOut());
    for (Map.Entry<String, String> entry : sqlAliasByEntityAlias.entrySet()) {
        final String userAlias = entry.getKey();
        final String drivingSqlAlias = entry.getValue();
        if (drivingSqlAlias == null) {
            throw new IllegalArgumentException("could not locate alias to apply lock mode : " + userAlias);
        }
        // at this point we have (drivingSqlAlias) the SQL alias of the driving table
        // corresponding to the given user alias.  However, the driving table is not
        // (necessarily) the table against which we want to apply locks.  Mainly,
        // the exception case here is joined-subclass hierarchies where we instead
        // want to apply the lock against the root table (for all other strategies,
        // it just happens that driving and root are the same).
        final QueryNode select = (QueryNode) queryTranslator.getSqlAST();
        final Lockable drivingPersister = (Lockable) select.getFromClause().findFromElementByUserOrSqlAlias(userAlias, drivingSqlAlias).getQueryable();
        final String sqlAlias = drivingPersister.getRootTableAlias(drivingSqlAlias);
        final LockMode effectiveLockMode = lockOptions.getEffectiveLockMode(userAlias);
        locks.setAliasSpecificLockMode(sqlAlias, effectiveLockMode);
        if (keyColumnNames != null) {
            keyColumnNames.put(sqlAlias, drivingPersister.getRootTableIdentifierColumnNames());
        }
    }
    // apply the collected locks and columns
    return dialect.applyLocksToSql(sql, locks, keyColumnNames);
}
Also used : LockOptions(org.hibernate.LockOptions) QueryNode(org.hibernate.hql.internal.ast.tree.QueryNode) Lockable(org.hibernate.persister.entity.Lockable) LockMode(org.hibernate.LockMode) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

HashMap (java.util.HashMap)2 LockMode (org.hibernate.LockMode)2 LockOptions (org.hibernate.LockOptions)2 Lockable (org.hibernate.persister.entity.Lockable)2 Map (java.util.Map)1 Session (org.hibernate.Session)1 SharedSessionContractImplementor (org.hibernate.engine.spi.SharedSessionContractImplementor)1 QueryNode (org.hibernate.hql.internal.ast.tree.QueryNode)1 AfterLoadAction (org.hibernate.loader.spi.AfterLoadAction)1 Loadable (org.hibernate.persister.entity.Loadable)1 OuterJoinLoadable (org.hibernate.persister.entity.OuterJoinLoadable)1