use of org.hibernate.engine.spi.Status in project hibernate-orm by hibernate.
the class DefaultFlushEntityEventListener method scheduleUpdate.
private boolean scheduleUpdate(final FlushEntityEvent event) {
final EntityEntry entry = event.getEntityEntry();
final EventSource session = event.getSession();
final Object entity = event.getEntity();
final Status status = entry.getStatus();
final EntityPersister persister = entry.getPersister();
final Object[] values = event.getPropertyValues();
if (LOG.isTraceEnabled()) {
if (status == Status.DELETED) {
if (!persister.isMutable()) {
LOG.tracev("Updating immutable, deleted entity: {0}", MessageHelper.infoString(persister, entry.getId(), session.getFactory()));
} else if (!entry.isModifiableEntity()) {
LOG.tracev("Updating non-modifiable, deleted entity: {0}", MessageHelper.infoString(persister, entry.getId(), session.getFactory()));
} else {
LOG.tracev("Updating deleted entity: ", MessageHelper.infoString(persister, entry.getId(), session.getFactory()));
}
} else {
LOG.tracev("Updating entity: {0}", MessageHelper.infoString(persister, entry.getId(), session.getFactory()));
}
}
final boolean intercepted = !entry.isBeingReplicated() && handleInterception(event);
// increment the version number (if necessary)
final Object nextVersion = getNextVersion(event);
// if it was dirtied by a collection only
int[] dirtyProperties = event.getDirtyProperties();
if (event.isDirtyCheckPossible() && dirtyProperties == null) {
if (!intercepted && !event.hasDirtyCollection()) {
throw new AssertionFailure("dirty, but no dirty properties");
}
dirtyProperties = ArrayHelper.EMPTY_INT_ARRAY;
}
// check nullability but do not doAfterTransactionCompletion command execute
// we'll use scheduled updates for that.
new Nullability(session).checkNullability(values, persister, true);
// schedule the update
// note that we intentionally do _not_ pass in currentPersistentState!
session.getActionQueue().addAction(new EntityUpdateAction(entry.getId(), values, dirtyProperties, event.hasDirtyCollection(), (status == Status.DELETED && !entry.isModifiableEntity() ? persister.getPropertyValues(entity) : entry.getLoadedState()), entry.getVersion(), nextVersion, entity, entry.getRowId(), persister, session));
return intercepted;
}
use of org.hibernate.engine.spi.Status in project hibernate-orm by hibernate.
the class AbstractFlushingEventListener method flushEntities.
/**
* 1. detect any dirty entities
* 2. schedule any entity updates
* 3. search out any reachable collections
*/
private int flushEntities(final FlushEvent event, final PersistenceContext persistenceContext) throws HibernateException {
LOG.trace("Flushing entities and processing referenced collections");
final EventSource source = event.getSession();
final Iterable<FlushEntityEventListener> flushListeners = source.getFactory().getServiceRegistry().getService(EventListenerRegistry.class).getEventListenerGroup(EventType.FLUSH_ENTITY).listeners();
// Among other things, updateReachables() will recursively load all
// collections that are moving roles. This might cause entities to
// be loaded.
// So this needs to be safe from concurrent modification problems.
final Map.Entry<Object, EntityEntry>[] entityEntries = persistenceContext.reentrantSafeEntityEntries();
final int count = entityEntries.length;
for (Map.Entry<Object, EntityEntry> me : entityEntries) {
// Update the status of the object and if necessary, schedule an update
EntityEntry entry = me.getValue();
Status status = entry.getStatus();
if (status != Status.LOADING && status != Status.GONE) {
final FlushEntityEvent entityEvent = new FlushEntityEvent(source, me.getKey(), entry);
for (FlushEntityEventListener listener : flushListeners) {
listener.onFlushEntity(entityEvent);
}
}
}
source.getActionQueue().sortActions();
return count;
}
use of org.hibernate.engine.spi.Status in project hibernate-orm by hibernate.
the class DefaultFlushEntityEventListener method onFlushEntity.
/**
* Flushes a single entity's state to the database, by scheduling
* an update action, if necessary
*/
public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
final Object entity = event.getEntity();
final EntityEntry entry = event.getEntityEntry();
final EventSource session = event.getSession();
final EntityPersister persister = entry.getPersister();
final Status status = entry.getStatus();
final Type[] types = persister.getPropertyTypes();
final boolean mightBeDirty = entry.requiresDirtyCheck(entity);
final Object[] values = getValues(entity, entry, mightBeDirty, session);
event.setPropertyValues(values);
// TODO: avoid this for non-new instances where mightBeDirty==false
boolean substitute = wrapCollections(session, persister, types, values);
if (isUpdateNecessary(event, mightBeDirty)) {
substitute = scheduleUpdate(event) || substitute;
}
if (status != Status.DELETED) {
// now update the object .. has to be outside the main if block above (because of collections)
if (substitute) {
persister.setPropertyValues(entity, values);
}
// We don't want to touch collections reachable from a deleted object
if (persister.hasCollections()) {
new FlushVisitor(session, entity).processEntityPropertyValues(values, types);
}
}
}
use of org.hibernate.engine.spi.Status in project hibernate-orm by hibernate.
the class DefaultFlushEntityEventListener method isUpdateNecessary.
/**
* Performs all necessary checking to determine if an entity needs an SQL update
* to synchronize its state to the database. Modifies the event by side-effect!
* Note: this method is quite slow, avoid calling if possible!
*/
protected final boolean isUpdateNecessary(FlushEntityEvent event) throws HibernateException {
EntityPersister persister = event.getEntityEntry().getPersister();
Status status = event.getEntityEntry().getStatus();
if (!event.isDirtyCheckPossible()) {
return true;
} else {
int[] dirtyProperties = event.getDirtyProperties();
if (dirtyProperties != null && dirtyProperties.length != 0) {
// TODO: suck into event class
return true;
} else {
return hasDirtyCollections(event, persister, status);
}
}
}
use of org.hibernate.engine.spi.Status in project hibernate-orm by hibernate.
the class AbstractEntityEntry method serialize.
@Override
public void serialize(ObjectOutputStream oos) throws IOException {
final Status previousStatus = getPreviousStatus();
oos.writeObject(getEntityName());
oos.writeObject(id);
oos.writeObject(getStatus().name());
oos.writeObject((previousStatus == null ? "" : previousStatus.name()));
// todo : potentially look at optimizing these two arrays
oos.writeObject(loadedState);
oos.writeObject(getDeletedState());
oos.writeObject(version);
oos.writeObject(getLockMode().toString());
oos.writeBoolean(isExistsInDatabase());
oos.writeBoolean(isBeingReplicated());
}
Aggregations