use of org.hibernate.reactive.pool.ReactiveConnection in project hibernate-reactive by hibernate.
the class ReactiveImprovedExtractionContextImpl method getQueryResultSet.
private ResultSet getQueryResultSet(String queryString, Object[] positionalParameters, CompletionStage<ReactiveConnection> connectionStage) {
final Object[] parametersToUse = positionalParameters != null ? positionalParameters : new Object[0];
final Parameters parametersDialectSpecific = Parameters.instance(getJdbcEnvironment().getDialect());
final String queryToUse = parametersDialectSpecific.process(queryString, parametersToUse.length);
return connectionStage.thenCompose(c -> c.selectJdbcOutsideTransaction(queryToUse, parametersToUse)).whenComplete((resultSet, err) -> logSqlException(err, () -> "could not execute query ", queryToUse)).thenApply(ResultSetWorkaround::new).toCompletableFuture().join();
}
use of org.hibernate.reactive.pool.ReactiveConnection in project hibernate-reactive by hibernate.
the class ReactiveAbstractEntityPersister method processGeneratedProperties.
default CompletionStage<Void> processGeneratedProperties(Serializable id, Object entity, Object[] state, SharedSessionContractImplementor session, String selectionSQL, GenerationTiming matchTiming) {
ReactiveConnection connection = getReactiveConnection(session);
// force immediate execution of the insert batch (if one)
return connection.executeBatch().thenCompose(v -> connection.selectJdbc(selectionSQL, bind(ps -> getIdentifierType().nullSafeSet(ps, id, 1, session)))).thenAccept(rs -> {
try {
if (!rs.next()) {
throw log.unableToRetrieveGeneratedProperties(infoString(this, id, getFactory()));
}
int propertyIndex = -1;
for (NonIdentifierAttribute attribute : getEntityMetamodel().getProperties()) {
propertyIndex++;
if (isValueGenerationRequired(attribute, matchTiming)) {
final Object hydratedState = attribute.getType().hydrate(rs, getPropertyAliases("", propertyIndex), session, entity);
state[propertyIndex] = attribute.getType().resolve(hydratedState, session, entity);
setPropertyValue(entity, propertyIndex, state[propertyIndex]);
}
}
} catch (SQLException sqle) {
// can never happen
throw new JDBCException("unable to select generated column values: " + selectionSQL, sqle);
}
});
}
use of org.hibernate.reactive.pool.ReactiveConnection in project hibernate-reactive by hibernate.
the class TableReactiveIdentifierGenerator method nextHiValue.
@Override
protected CompletionStage<Long> nextHiValue(ReactiveConnectionSupplier session) {
// We need to read the current hi value from the table
// and update it by the specified increment, but we
// need to do it atomically, and without depending on
// transaction rollback.
ReactiveConnection connection = session.getReactiveConnection();
// 1) select the current hi value
return connection.selectIdentifier(selectQuery, selectParameters(), Long.class).thenCompose(result -> {
Object[] params;
String sql;
long id;
if (result == null) {
// if there is no row in the table, insert one
// TODO: This not threadsafe, and can result in
// multiple rows being inserted simultaneously.
// It might be better to just throw an exception
// here, and require that the table was populated
// when it was created
id = initialValue;
long insertedValue = storeLastUsedValue ? id - increment : id;
params = insertParameters(insertedValue);
sql = insertQuery;
} else {
// otherwise, update the existing row
long currentValue = result;
long updatedValue = currentValue + increment;
id = storeLastUsedValue ? updatedValue : currentValue;
params = updateParameters(currentValue, updatedValue);
sql = updateQuery;
}
return connection.update(sql, params).thenCompose(rowCount -> {
switch(rowCount) {
case 1:
// we successfully obtained the next hi value
return completedFuture(id);
case 0:
// so retry everything from scratch
return nextHiValue(session);
default:
throw new TooManyRowsAffectedException("multiple rows in id table", 1, rowCount);
}
});
});
}
use of org.hibernate.reactive.pool.ReactiveConnection in project hibernate-reactive by hibernate.
the class ReactiveAbstractCollectionPersister method recreateReactive.
/**
* @see org.hibernate.persister.collection.AbstractCollectionPersister#recreate(PersistentCollection, Serializable, SharedSessionContractImplementor)
*/
default CompletionStage<Void> recreateReactive(PersistentCollection collection, Serializable id, SharedSessionContractImplementor session) throws HibernateException {
if (isInverse() || !isRowInsertEnabled()) {
return voidFuture();
}
if (LOG.isDebugEnabled()) {
LOG.debugf("Inserting collection: %s", collectionInfoString(this, collection, id, session));
}
ReactiveConnection connection = getReactiveConnection(session);
// TODO: compose() reactive version of collection.preInsert()
Iterator<?> entries = collection.entries(this);
Expectation expectation = appropriateExpectation(getInsertCheckStyle());
return loop(entries, collection::entryExists, (entry, index) -> connection.update(getSQLInsertRowString(), insertRowsParamValues(entry, index, collection, id, session), expectation.canBeBatched(), new ExpectationAdaptor(expectation, getSQLInsertRowString(), getSqlExceptionConverter())));
// TODO: compose() reactive version of collection.afterRowInsert()
}
use of org.hibernate.reactive.pool.ReactiveConnection in project hibernate-reactive by hibernate.
the class ReactiveAbstractCollectionPersister method reactiveDeleteRows.
/**
* @see org.hibernate.persister.collection.AbstractCollectionPersister#deleteRows(PersistentCollection, Serializable, SharedSessionContractImplementor)
*/
@Override
default CompletionStage<Void> reactiveDeleteRows(PersistentCollection collection, Serializable id, SharedSessionContractImplementor session) {
if (isInverse() || !isRowDeleteEnabled()) {
return voidFuture();
}
Iterator<?> deletes = collection.getDeletes(this, !deleteByIndex());
if (!deletes.hasNext()) {
return voidFuture();
}
ReactiveConnection connection = getReactiveConnection(session);
Expectation expectation = appropriateExpectation(getDeleteCheckStyle());
return loop(deletes, (entry, index) -> connection.update(getSQLDeleteRowString(), deleteRowsParamValues(entry, 1, id, session), expectation.canBeBatched(), new ExpectationAdaptor(expectation, getSQLDeleteRowString(), getSqlExceptionConverter())));
}
Aggregations