use of org.hibernate.tuple.InMemoryValueGenerationStrategy in project hibernate-orm by hibernate.
the class AbstractEntityPersister method update.
/**
* Update an object
*/
public void update(final Serializable id, final Object[] fields, final int[] dirtyFields, final boolean hasDirtyCollection, final Object[] oldFields, final Object oldVersion, final Object object, final Object rowId, final SharedSessionContractImplementor session) throws HibernateException {
// apply any pre-update in-memory value generation
if (getEntityMetamodel().hasPreUpdateGeneratedValues()) {
final InMemoryValueGenerationStrategy[] strategies = getEntityMetamodel().getInMemoryValueGenerationStrategies();
for (int i = 0; i < strategies.length; i++) {
if (strategies[i] != null && strategies[i].getGenerationTiming().includesUpdate()) {
fields[i] = strategies[i].getValueGenerator().generateValue((Session) session, object);
setPropertyValue(object, i, fields[i]);
// todo : probably best to add to dirtyFields if not-null
}
}
}
//note: dirtyFields==null means we had no snapshot, and we couldn't get one using select-beforeQuery-update
// oldFields==null just means we had no snapshot to begin with (we might have used select-beforeQuery-update to get the dirtyFields)
final boolean[] tableUpdateNeeded = getTableUpdateNeeded(dirtyFields, hasDirtyCollection);
final int span = getTableSpan();
final boolean[] propsToUpdate;
final String[] updateStrings;
EntityEntry entry = session.getPersistenceContext().getEntry(object);
// in the process of being deleted.
if (entry == null && !isMutable()) {
throw new IllegalStateException("Updating immutable entity that is not in session yet!");
}
if ((entityMetamodel.isDynamicUpdate() && dirtyFields != null)) {
// We need to generate the UPDATE SQL when dynamic-update="true"
propsToUpdate = 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++) {
updateStrings[j] = tableUpdateNeeded[j] ? generateUpdateString(propsToUpdate, j, oldFields, j == 0 && rowId != null) : null;
}
} else if (!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 beforeQuery 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 = 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++) {
updateStrings[j] = tableUpdateNeeded[j] ? generateUpdateString(propsToUpdate, j, oldFields, j == 0 && rowId != null) : null;
}
} else {
// For the case of dynamic-update="false", or no snapshot, we use the static SQL
updateStrings = getUpdateStrings(rowId != null, hasUninitializedLazyProperties(object));
propsToUpdate = getPropertyUpdateability(object);
}
for (int j = 0; j < span; j++) {
// Now update only the tables with dirty properties (and the table with the version number)
if (tableUpdateNeeded[j]) {
updateOrInsert(id, fields, oldFields, j == 0 ? rowId : null, propsToUpdate, j, oldVersion, object, updateStrings[j], session);
}
}
}
Aggregations