Search in sources :

Example 1 with Status

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;
}
Also used : Status(org.hibernate.engine.spi.Status) EntityPersister(org.hibernate.persister.entity.EntityPersister) EntityEntry(org.hibernate.engine.spi.EntityEntry) EventSource(org.hibernate.event.spi.EventSource) AssertionFailure(org.hibernate.AssertionFailure) EntityUpdateAction(org.hibernate.action.internal.EntityUpdateAction) Nullability(org.hibernate.engine.internal.Nullability)

Example 2 with Status

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;
}
Also used : Status(org.hibernate.engine.spi.Status) EventSource(org.hibernate.event.spi.EventSource) CollectionEntry(org.hibernate.engine.spi.CollectionEntry) EntityEntry(org.hibernate.engine.spi.EntityEntry) EntityEntry(org.hibernate.engine.spi.EntityEntry) FlushEntityEvent(org.hibernate.event.spi.FlushEntityEvent) FlushEntityEventListener(org.hibernate.event.spi.FlushEntityEventListener) Map(java.util.Map) IdentityMap(org.hibernate.internal.util.collections.IdentityMap) IdentityHashMap(java.util.IdentityHashMap) CascadePoint(org.hibernate.engine.internal.CascadePoint)

Example 3 with Status

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);
        }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Status(org.hibernate.engine.spi.Status) EntityEntry(org.hibernate.engine.spi.EntityEntry) EventSource(org.hibernate.event.spi.EventSource) Type(org.hibernate.type.Type)

Example 4 with Status

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);
        }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Status(org.hibernate.engine.spi.Status)

Example 5 with 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());
}
Also used : Status(org.hibernate.engine.spi.Status)

Aggregations

Status (org.hibernate.engine.spi.Status)11 EntityEntry (org.hibernate.engine.spi.EntityEntry)6 EntityPersister (org.hibernate.persister.entity.EntityPersister)5 EventSource (org.hibernate.event.spi.EventSource)3 IdentityHashMap (java.util.IdentityHashMap)2 Map (java.util.Map)2 IdentityMap (org.hibernate.internal.util.collections.IdentityMap)2 AssertionFailure (org.hibernate.AssertionFailure)1 EntityUpdateAction (org.hibernate.action.internal.EntityUpdateAction)1 CascadePoint (org.hibernate.engine.internal.CascadePoint)1 Nullability (org.hibernate.engine.internal.Nullability)1 CollectionEntry (org.hibernate.engine.spi.CollectionEntry)1 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)1 FlushEntityEvent (org.hibernate.event.spi.FlushEntityEvent)1 FlushEntityEventListener (org.hibernate.event.spi.FlushEntityEventListener)1 Type (org.hibernate.type.Type)1