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