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);
}
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);
}
Aggregations