Search in sources :

Example 1 with TooManyRowsAffectedException

use of org.hibernate.jdbc.TooManyRowsAffectedException 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);
            }
        });
    });
}
Also used : ReactiveConnection(org.hibernate.reactive.pool.ReactiveConnection) TooManyRowsAffectedException(org.hibernate.jdbc.TooManyRowsAffectedException) ConfigurationHelper.getString(org.hibernate.internal.util.config.ConfigurationHelper.getString)

Aggregations

ConfigurationHelper.getString (org.hibernate.internal.util.config.ConfigurationHelper.getString)1 TooManyRowsAffectedException (org.hibernate.jdbc.TooManyRowsAffectedException)1 ReactiveConnection (org.hibernate.reactive.pool.ReactiveConnection)1