Search in sources :

Example 31 with LockOptions

use of org.hibernate.LockOptions in project hibernate-orm by hibernate.

the class CriteriaQueryTranslator method getQueryParameters.

public QueryParameters getQueryParameters() {
    final RowSelection selection = new RowSelection();
    selection.setFirstRow(rootCriteria.getFirstResult());
    selection.setMaxRows(rootCriteria.getMaxResults());
    selection.setTimeout(rootCriteria.getTimeout());
    selection.setFetchSize(rootCriteria.getFetchSize());
    final LockOptions lockOptions = new LockOptions();
    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()) {
        final CriteriaImpl.Subcriteria subcriteria = subcriteriaIterator.next();
        final LockMode lm = subcriteria.getLockMode();
        if (lm != null) {
            lockOptions.setAliasSpecificLockMode(getSQLAlias(subcriteria), lm);
        }
        if (subcriteria.getWithClause() != null) {
            final 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).
    final Iterator<CriteriaImpl.CriterionEntry> iter = rootCriteria.iterateExpressionEntries();
    while (iter.hasNext()) {
        final CriteriaImpl.CriterionEntry ce = iter.next();
        final TypedValue[] tv = ce.getCriterion().getTypedValues(ce.getCriteria(), this);
        for (TypedValue aTv : tv) {
            values.add(aTv.getValue());
            types.add(aTv.getType());
        }
    }
    final Object[] valueArray = values.toArray();
    final 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());
}
Also used : LockOptions(org.hibernate.LockOptions) CriteriaImpl(org.hibernate.internal.CriteriaImpl) ArrayList(java.util.ArrayList) LockMode(org.hibernate.LockMode) Criteria(org.hibernate.Criteria) QueryParameters(org.hibernate.engine.spi.QueryParameters) RowSelection(org.hibernate.engine.spi.RowSelection) StringRepresentableType(org.hibernate.type.StringRepresentableType) CollectionType(org.hibernate.type.CollectionType) JoinType(org.hibernate.sql.JoinType) AssociationType(org.hibernate.type.AssociationType) Type(org.hibernate.type.Type) TypedValue(org.hibernate.engine.spi.TypedValue)

Example 32 with LockOptions

use of org.hibernate.LockOptions in project hibernate-orm by hibernate.

the class CustomLoader 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)) {
        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(SharedSessionContractImplementor session, Object entity, Loadable persister) {
            ((Session) session).buildLockRequest(originalLockOptions).lock(persister.getEntityName(), entity);
        }
    });
    parameters.getLockOptions().setLockMode(LockMode.READ);
    return sql;
}
Also used : Loadable(org.hibernate.persister.entity.Loadable) LockOptions(org.hibernate.LockOptions) AfterLoadAction(org.hibernate.loader.spi.AfterLoadAction) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) Session(org.hibernate.Session)

Example 33 with LockOptions

use of org.hibernate.LockOptions in project hibernate-orm by hibernate.

the class AbstractLoadPlanBasedLoader method prepareQueryStatement.

/**
	 * Obtain a <tt>PreparedStatement</tt> with all parameters pre-bound.
	 * Bind JDBC-style <tt>?</tt> parameters, named parameters, and
	 * limit parameters.
	 */
protected final PreparedStatement prepareQueryStatement(final String sql, final QueryParameters queryParameters, final LimitHandler limitHandler, final boolean scroll, final SharedSessionContractImplementor session) throws SQLException, HibernateException {
    final Dialect dialect = session.getJdbcServices().getJdbcEnvironment().getDialect();
    final RowSelection selection = queryParameters.getRowSelection();
    final boolean useLimit = LimitHelper.useLimit(limitHandler, selection);
    final boolean hasFirstRow = LimitHelper.hasFirstRow(selection);
    final boolean useLimitOffset = hasFirstRow && useLimit && limitHandler.supportsLimitOffset();
    final boolean callable = queryParameters.isCallable();
    final ScrollMode scrollMode = getScrollMode(scroll, hasFirstRow, useLimitOffset, queryParameters);
    final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareQueryStatement(sql, callable, scrollMode);
    try {
        int col = 1;
        //TODO: can we limit stored procedures ?!
        col += limitHandler.bindLimitParametersAtStartOfQuery(selection, st, col);
        if (callable) {
            col = dialect.registerResultSetOutParameter((CallableStatement) st, col);
        }
        col += bindParameterValues(st, queryParameters, col, session);
        col += limitHandler.bindLimitParametersAtEndOfQuery(selection, st, col);
        limitHandler.setMaxRows(selection, st);
        if (selection != null) {
            if (selection.getTimeout() != null) {
                st.setQueryTimeout(selection.getTimeout());
            }
            if (selection.getFetchSize() != null) {
                st.setFetchSize(selection.getFetchSize());
            }
        }
        // handle lock timeout...
        final LockOptions lockOptions = queryParameters.getLockOptions();
        if (lockOptions != null) {
            if (lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER) {
                if (!dialect.supportsLockTimeouts()) {
                    if (log.isDebugEnabled()) {
                        log.debugf("Lock timeout [%s] requested but dialect reported to not support lock timeouts", lockOptions.getTimeOut());
                    }
                } else if (dialect.isLockTimeoutParameterized()) {
                    st.setInt(col++, lockOptions.getTimeOut());
                }
            }
        }
        if (log.isTraceEnabled()) {
            log.tracev("Bound [{0}] parameters total", col);
        }
    } catch (SQLException sqle) {
        session.getJdbcCoordinator().getResourceRegistry().release(st);
        session.getJdbcCoordinator().afterStatementExecution();
        throw sqle;
    } catch (HibernateException he) {
        session.getJdbcCoordinator().getResourceRegistry().release(st);
        session.getJdbcCoordinator().afterStatementExecution();
        throw he;
    }
    return st;
}
Also used : ScrollMode(org.hibernate.ScrollMode) LockOptions(org.hibernate.LockOptions) SQLException(java.sql.SQLException) HibernateException(org.hibernate.HibernateException) CallableStatement(java.sql.CallableStatement) Dialect(org.hibernate.dialect.Dialect) PreparedStatement(java.sql.PreparedStatement) RowSelection(org.hibernate.engine.spi.RowSelection)

Example 34 with LockOptions

use of org.hibernate.LockOptions in project hibernate-orm by hibernate.

the class DynamicBatchingEntityLoaderBuilder method performUnorderedMultiLoad.

@SuppressWarnings("unchecked")
protected List performUnorderedMultiLoad(OuterJoinLoadable persister, Serializable[] ids, SharedSessionContractImplementor session, MultiLoadOptions loadOptions) {
    assert !loadOptions.isOrderReturnEnabled();
    final List result = CollectionHelper.arrayList(ids.length);
    if (loadOptions.isSessionCheckingEnabled()) {
        // the user requested that we exclude ids corresponding to already managed
        // entities from the generated load SQL.  So here we will iterate all
        // incoming id values and see whether it corresponds to an existing
        // entity associated with the PC - if it does we add it to the result
        // list immediately and remove its id from the group of ids to load.
        boolean foundAnyManagedEntities = false;
        final List<Serializable> nonManagedIds = new ArrayList<Serializable>();
        for (Serializable id : ids) {
            final EntityKey entityKey = new EntityKey(id, persister);
            final Object managedEntity = session.getPersistenceContext().getEntity(entityKey);
            if (managedEntity != null) {
                if (!loadOptions.isReturnOfDeletedEntitiesEnabled()) {
                    final EntityEntry entry = session.getPersistenceContext().getEntry(managedEntity);
                    if (entry.getStatus() == Status.DELETED || entry.getStatus() == Status.GONE) {
                        continue;
                    }
                }
                foundAnyManagedEntities = true;
                result.add(managedEntity);
            } else {
                nonManagedIds.add(id);
            }
        }
        if (foundAnyManagedEntities) {
            if (nonManagedIds.isEmpty()) {
                // all of the given ids were already associated with the Session
                return result;
            } else {
                // over-write the ids to be loaded with the collection of
                // just non-managed ones
                ids = nonManagedIds.toArray((Serializable[]) Array.newInstance(ids.getClass().getComponentType(), nonManagedIds.size()));
            }
        }
    }
    final LockOptions lockOptions = (loadOptions.getLockOptions() == null) ? new LockOptions(LockMode.NONE) : loadOptions.getLockOptions();
    int numberOfIdsLeft = ids.length;
    final int maxBatchSize;
    if (loadOptions.getBatchSize() != null && loadOptions.getBatchSize() > 0) {
        maxBatchSize = loadOptions.getBatchSize();
    } else {
        maxBatchSize = session.getJdbcServices().getJdbcEnvironment().getDialect().getDefaultBatchLoadSizingStrategy().determineOptimalBatchLoadSize(persister.getIdentifierType().getColumnSpan(session.getFactory()), numberOfIdsLeft);
    }
    int idPosition = 0;
    while (numberOfIdsLeft > 0) {
        int batchSize = Math.min(numberOfIdsLeft, maxBatchSize);
        final DynamicEntityLoader batchingLoader = new DynamicEntityLoader(persister, batchSize, lockOptions, session.getFactory(), session.getLoadQueryInfluencers());
        Serializable[] idsInBatch = new Serializable[batchSize];
        System.arraycopy(ids, idPosition, idsInBatch, 0, batchSize);
        QueryParameters qp = buildMultiLoadQueryParameters(persister, idsInBatch, lockOptions);
        result.addAll(batchingLoader.doEntityBatchFetch(session, qp, idsInBatch));
        numberOfIdsLeft = numberOfIdsLeft - batchSize;
        idPosition += batchSize;
    }
    return result;
}
Also used : Serializable(java.io.Serializable) LockOptions(org.hibernate.LockOptions) ArrayList(java.util.ArrayList) QueryParameters(org.hibernate.engine.spi.QueryParameters) EntityKey(org.hibernate.engine.spi.EntityKey) EntityEntry(org.hibernate.engine.spi.EntityEntry) ArrayList(java.util.ArrayList) List(java.util.List)

Example 35 with LockOptions

use of org.hibernate.LockOptions 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

LockOptions (org.hibernate.LockOptions)64 Test (org.junit.Test)43 Session (org.hibernate.Session)23 TestForIssue (org.hibernate.testing.TestForIssue)14 PersistenceException (javax.persistence.PersistenceException)5 SQLGrammarException (org.hibernate.exception.SQLGrammarException)5 LockMode (org.hibernate.LockMode)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 RowSelection (org.hibernate.engine.spi.RowSelection)3 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)3 SharedSessionContractImplementor (org.hibernate.engine.spi.SharedSessionContractImplementor)3 AfterLoadAction (org.hibernate.loader.spi.AfterLoadAction)3 Loadable (org.hibernate.persister.entity.Loadable)3 RequiresDialect (org.hibernate.testing.RequiresDialect)3 Serializable (java.io.Serializable)2 CallableStatement (java.sql.CallableStatement)2 PreparedStatement (java.sql.PreparedStatement)2 SQLException (java.sql.SQLException)2