use of org.hibernate.reactive.pool.ReactiveConnection in project hibernate-reactive by hibernate.
the class ReactiveAbstractEntityPersister method lockReactive.
@Override
default CompletionStage<Void> lockReactive(Serializable id, Object version, Object object, LockOptions lockOptions, SharedSessionContractImplementor session) throws HibernateException {
LockMode lockMode = lockOptions.getLockMode();
Object nextVersion = nextVersionForLock(lockMode, id, version, object, session);
String sql;
boolean writeLock;
switch(lockMode) {
// 0) noop
case NONE:
return voidFuture();
// 1) select ... for share
case PESSIMISTIC_READ:
// 2) select ... for update
case PESSIMISTIC_WRITE:
case UPGRADE:
// 3) select ... for nowait
case UPGRADE_NOWAIT:
// 4) select ... for update skip locked
case UPGRADE_SKIPLOCKED:
// TODO: introduce separate support for PESSIMISTIC_READ
// the current implementation puts the version number in
// the where clause and the id in the select list, whereas
// it would be better to actually select and check the
// version number (same problem in hibernate-core)
sql = generateSelectLockString(lockOptions);
writeLock = false;
break;
// 5) update ... set version
case PESSIMISTIC_FORCE_INCREMENT:
case FORCE:
sql = generateUpdateLockString(lockOptions);
writeLock = true;
break;
// locks obtained in the before completion phase
case OPTIMISTIC:
case OPTIMISTIC_FORCE_INCREMENT:
throw new AssertionFailure("optimistic lock mode is not supported here");
// other operations
case READ:
case WRITE:
throw new AssertionFailure("implicit lock mode is not supported here");
default:
throw new AssertionFailure("illegal lock mode");
}
Object[] arguments = PreparedStatementAdaptor.bind(statement -> {
int offset = 1;
if (writeLock) {
getVersionType().nullSafeSet(statement, nextVersion, offset, session);
offset++;
}
getIdentifierType().nullSafeSet(statement, id, offset, session);
offset += getIdentifierType().getColumnSpan(getFactory());
if (isVersioned()) {
getVersionType().nullSafeSet(statement, version, offset, session);
}
});
ReactiveConnection connection = getReactiveConnection(session);
CompletionStage<Boolean> lock = writeLock ? connection.update(sql, arguments).thenApply(affected -> affected > 0) : connection.select(sql, arguments).thenApply(Iterator::hasNext);
return lock.thenAccept(rowExisted -> {
if (!rowExisted) {
throw new StaleObjectStateException(getEntityName(), id);
}
}).handle((r, e) -> {
logSqlException(e, () -> "could not lock: " + infoString(this, id, getFactory()), sql);
return returnOrRethrow(e, r);
});
}
use of org.hibernate.reactive.pool.ReactiveConnection in project hibernate-reactive by hibernate.
the class ReactiveAbstractCollectionPersister method reactiveInsertRows.
/**
* @see org.hibernate.persister.collection.AbstractCollectionPersister#insertRows(PersistentCollection, Serializable, SharedSessionContractImplementor)
*/
@Override
default CompletionStage<Void> reactiveInsertRows(PersistentCollection collection, Serializable id, SharedSessionContractImplementor session) {
if (isInverse() || !isRowDeleteEnabled()) {
return voidFuture();
}
if (LOG.isDebugEnabled()) {
LOG.debugf("Inserting rows of collection: %s", collectionInfoString(this, collection, id, session));
}
ReactiveConnection connection = getReactiveConnection(session);
// TODO: compose() reactive version of collection.preInsert()
List<Object> entries = entryList(collection);
if (!needsInsert(collection, entries)) {
return voidFuture();
}
Expectation expectation = appropriateExpectation(getInsertCheckStyle());
return loop(entries.iterator(), (entry, index) -> collection.needsInserting(entry, index, getElementType()), (entry, index) -> connection.update(getSQLInsertRowString(), insertRowsParamValues(entry, index, collection, id, session), expectation.canBeBatched(), new ExpectationAdaptor(expectation, getSQLInsertRowString(), getSqlExceptionConverter()))).thenAccept(total -> LOG.debugf("Done inserting rows: %s inserted", total));
}
use of org.hibernate.reactive.pool.ReactiveConnection in project hibernate-reactive by hibernate.
the class ReactiveBulkIdStrategy method release.
@Override
public void release(JdbcServices jdbcServices, JdbcConnectionAccess connectionAccess) {
if (serviceRegistry != null && !dropGlobalTemporaryTables.isEmpty()) {
boolean dropIdTables = serviceRegistry.getService(ConfigurationService.class).getSetting(GlobalTemporaryTableBulkIdStrategy.DROP_ID_TABLES, StandardConverters.BOOLEAN, false);
if (dropIdTables) {
ReactiveConnection connection = serviceRegistry.getService(ReactiveConnectionPool.class).getProxyConnection();
loop(dropGlobalTemporaryTables, connection::execute).whenComplete((v, e) -> connection.close()).handle(CompletionStages::ignoreErrors).toCompletableFuture().join();
}
}
}
Aggregations