use of org.hibernate.reactive.stage.Stage in project hibernate-reactive by hibernate.
the class ReactiveAbstractEntityPersister method updateReactive.
default CompletionStage<Void> updateReactive(final Serializable id, final Object[] fields, int[] paramDirtyFields, final boolean hasDirtyCollection, final Object[] oldFields, final Object oldVersion, final Object object, final Object rowId, final SharedSessionContractImplementor session) {
CompletionStage<Void> stage = voidFuture();
CompletionStage<int[]> dirtyFieldsStage = completedFuture(paramDirtyFields);
// apply any pre-update in-memory value generation
if (delegate().getEntityMetamodel().hasPreUpdateGeneratedValues()) {
final InMemoryValueGenerationStrategy[] valueGenerationStrategies = delegate().getEntityMetamodel().getInMemoryValueGenerationStrategies();
int valueGenerationStrategiesSize = valueGenerationStrategies.length;
if (valueGenerationStrategiesSize != 0) {
int[] fieldsPreUpdateNeeded = new int[valueGenerationStrategiesSize];
int count = 0;
for (int i = 0; i < valueGenerationStrategiesSize; i++) {
final int index = i;
if (valueGenerationStrategies[i] != null && valueGenerationStrategies[i].getGenerationTiming().includesUpdate()) {
stage = stage.thenCompose(v -> generateValue(object, session, valueGenerationStrategies[index]).thenAccept(value -> setFieldValue(fields, object, index, value)));
fieldsPreUpdateNeeded[count++] = i;
}
}
final int finalCount = count;
dirtyFieldsStage = stage.thenApply(v -> paramDirtyFields != null ? join(paramDirtyFields, trim(fieldsPreUpdateNeeded, finalCount)) : null);
}
}
return dirtyFieldsStage.thenCompose(dirtyFields -> {
// note: dirtyFields==null means we had no snapshot, and we couldn't get one using select-before-update
// oldFields==null just means we had no snapshot to begin with (we might have used select-before-update to get the dirtyFields)
final boolean[] tableUpdateNeeded = delegate().getTableUpdateNeeded(dirtyFields, hasDirtyCollection);
final int span = delegate().getTableSpan();
final boolean[] propsToUpdate;
final String[] updateStrings;
EntityEntry entry = session.getPersistenceContextInternal().getEntry(object);
// in the process of being deleted.
if (entry == null && !delegate().isMutable()) {
throw log.updatingImmutableEntityThatsNotInTheSession();
}
if ((delegate().getEntityMetamodel().isDynamicUpdate() && dirtyFields != null)) {
// We need to generate the UPDATE SQL when dynamic-update="true"
propsToUpdate = delegate().getPropertiesToUpdate(dirtyFields, hasDirtyCollection);
// don't need to check laziness (dirty checking algorithm handles that)
updateStrings = new String[span];
for (int j = 0; j < span; j++) {
final boolean useRowId = j == 0 && rowId != null;
updateStrings[j] = tableUpdateNeeded[j] ? delegate().generateUpdateString(propsToUpdate, j, oldFields, useRowId) : null;
}
} else if (!delegate().isModifiableEntity(entry)) {
// We need to generate UPDATE SQL when a non-modifiable entity (e.g., read-only or immutable)
// needs:
// - to have references to transient entities set to null before being deleted
// - to have version incremented do to a "dirty" association
// If dirtyFields == null, then that means that there are no dirty properties to
// to be updated; an empty array for the dirty fields needs to be passed to
// getPropertiesToUpdate() instead of null.
propsToUpdate = delegate().getPropertiesToUpdate(dirtyFields == null ? ArrayHelper.EMPTY_INT_ARRAY : dirtyFields, hasDirtyCollection);
// don't need to check laziness (dirty checking algorithm handles that)
updateStrings = new String[span];
for (int j = 0; j < span; j++) {
final boolean useRowId = j == 0 && rowId != null;
updateStrings[j] = tableUpdateNeeded[j] ? delegate().generateUpdateString(propsToUpdate, j, oldFields, useRowId) : null;
}
} else {
// For the case of dynamic-update="false", or no snapshot, we use the static SQL
boolean hasUninitializedLazy = delegate().hasUninitializedLazyProperties(object);
updateStrings = getUpdateStrings(rowId != null, hasUninitializedLazy);
propsToUpdate = delegate().getPropertyUpdateability(object);
}
// Now update only the tables with dirty properties (and the table with the version number)
return loop(0, span, i -> tableUpdateNeeded[i], table -> updateOrInsertReactive(id, fields, oldFields, table == 0 ? rowId : null, propsToUpdate, table, oldVersion, updateStrings[table], session));
});
}
use of org.hibernate.reactive.stage.Stage in project hibernate-reactive by hibernate.
the class ReactiveAbstractEntityPersister method reactivePreInsertInMemoryValueGeneration.
default CompletionStage<Void> reactivePreInsertInMemoryValueGeneration(Object[] fields, Object object, SharedSessionContractImplementor session) {
CompletionStage<Void> stage = voidFuture();
if (getEntityMetamodel().hasPreInsertGeneratedValues()) {
final InMemoryValueGenerationStrategy[] strategies = getEntityMetamodel().getInMemoryValueGenerationStrategies();
for (int i = 0; i < strategies.length; i++) {
final int index = i;
final InMemoryValueGenerationStrategy strategy = strategies[i];
if (strategy != null && strategy.getGenerationTiming().includesInsert()) {
stage = stage.thenCompose(v -> generateValue(object, session, strategy).thenAccept(value -> {
fields[index] = value;
setPropertyValue(object, index, value);
}));
}
}
}
return stage;
}
Aggregations