Search in sources :

Example 6 with EventSource

use of org.hibernate.event.spi.EventSource in project hibernate-orm by hibernate.

the class DefaultEvictEventListener method onEvict.

/**
	 * Handle the given evict event.
	 *
	 * @param event The evict event to be handled.
	 *
	 * @throws HibernateException
	 */
public void onEvict(EvictEvent event) throws HibernateException {
    final Object object = event.getObject();
    if (object == null) {
        throw new NullPointerException("null passed to Session.evict()");
    }
    final EventSource source = event.getSession();
    final PersistenceContext persistenceContext = source.getPersistenceContext();
    if (object instanceof HibernateProxy) {
        final LazyInitializer li = ((HibernateProxy) object).getHibernateLazyInitializer();
        final Serializable id = li.getIdentifier();
        if (id == null) {
            throw new IllegalArgumentException("Could not determine identifier of proxy passed to evict()");
        }
        final EntityPersister persister = source.getFactory().getEntityPersister(li.getEntityName());
        final EntityKey key = source.generateEntityKey(id, persister);
        persistenceContext.removeProxy(key);
        if (!li.isUninitialized()) {
            final Object entity = persistenceContext.removeEntity(key);
            if (entity != null) {
                EntityEntry e = persistenceContext.removeEntry(entity);
                doEvict(entity, key, e.getPersister(), event.getSession());
            }
        }
        li.unsetSession();
    } else {
        EntityEntry e = persistenceContext.removeEntry(object);
        if (e != null) {
            persistenceContext.removeEntity(e.getEntityKey());
            doEvict(object, e.getEntityKey(), e.getPersister(), source);
        } else {
            // see if the passed object is even an entity, and if not throw an exception
            // 		this is different than legacy Hibernate behavior, but what JPA 2.1 is calling for
            //		with EntityManager.detach
            EntityPersister persister = null;
            final String entityName = persistenceContext.getSession().guessEntityName(object);
            if (entityName != null) {
                try {
                    persister = persistenceContext.getSession().getFactory().getEntityPersister(entityName);
                } catch (Exception ignore) {
                }
            }
            if (persister == null) {
                throw new IllegalArgumentException("Non-entity object instance passed to evict : " + object);
            }
        }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) LazyInitializer(org.hibernate.proxy.LazyInitializer) Serializable(java.io.Serializable) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) HibernateProxy(org.hibernate.proxy.HibernateProxy) HibernateException(org.hibernate.HibernateException) EntityKey(org.hibernate.engine.spi.EntityKey) EventSource(org.hibernate.event.spi.EventSource) EntityEntry(org.hibernate.engine.spi.EntityEntry)

Example 7 with EventSource

use of org.hibernate.event.spi.EventSource 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 8 with EventSource

use of org.hibernate.event.spi.EventSource 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 9 with EventSource

use of org.hibernate.event.spi.EventSource in project hibernate-orm by hibernate.

the class DefaultFlushEventListener method onFlush.

/** Handle the given flush event.
	 *
	 * @param event The flush event to be handled.
	 * @throws HibernateException
	 */
public void onFlush(FlushEvent event) throws HibernateException {
    final EventSource source = event.getSession();
    final PersistenceContext persistenceContext = source.getPersistenceContext();
    if (persistenceContext.getNumberOfManagedEntities() > 0 || persistenceContext.getCollectionEntries().size() > 0) {
        try {
            source.getEventListenerManager().flushStart();
            flushEverythingToExecutions(event);
            performExecutions(source);
            postFlush(source);
        } finally {
            source.getEventListenerManager().flushEnd(event.getNumberOfEntitiesProcessed(), event.getNumberOfCollectionsProcessed());
        }
        postPostFlush(source);
        if (source.getFactory().getStatistics().isStatisticsEnabled()) {
            source.getFactory().getStatistics().flush();
        }
    }
}
Also used : EventSource(org.hibernate.event.spi.EventSource) PersistenceContext(org.hibernate.engine.spi.PersistenceContext)

Example 10 with EventSource

use of org.hibernate.event.spi.EventSource in project hibernate-orm by hibernate.

the class DefaultMergeEventListener method onMerge.

/**
	 * Handle the given merge event.
	 *
	 * @param event The merge event to be handled.
	 *
	 * @throws HibernateException
	 */
public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException {
    final MergeContext copyCache = (MergeContext) copiedAlready;
    final EventSource source = event.getSession();
    final Object original = event.getOriginal();
    if (original != null) {
        final Object entity;
        if (original instanceof HibernateProxy) {
            LazyInitializer li = ((HibernateProxy) original).getHibernateLazyInitializer();
            if (li.isUninitialized()) {
                LOG.trace("Ignoring uninitialized proxy");
                event.setResult(source.load(li.getEntityName(), li.getIdentifier()));
                //EARLY EXIT!
                return;
            } else {
                entity = li.getImplementation();
            }
        } else {
            entity = original;
        }
        if (copyCache.containsKey(entity) && (copyCache.isOperatedOn(entity))) {
            LOG.trace("Already in merge process");
            event.setResult(entity);
        } else {
            if (copyCache.containsKey(entity)) {
                LOG.trace("Already in copyCache; setting in merge process");
                copyCache.setOperatedOn(entity, true);
            }
            event.setEntity(entity);
            EntityState entityState = null;
            // Check the persistence context for an entry relating to this
            // entity to be merged...
            EntityEntry entry = source.getPersistenceContext().getEntry(entity);
            if (entry == null) {
                EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
                Serializable id = persister.getIdentifier(entity, source);
                if (id != null) {
                    final EntityKey key = source.generateEntityKey(id, persister);
                    final Object managedEntity = source.getPersistenceContext().getEntity(key);
                    entry = source.getPersistenceContext().getEntry(managedEntity);
                    if (entry != null) {
                        // we have specialized case of a detached entity from the
                        // perspective of the merge operation.  Specifically, we
                        // have an incoming entity instance which has a corresponding
                        // entry in the current persistence context, but registered
                        // under a different entity instance
                        entityState = EntityState.DETACHED;
                    }
                }
            }
            if (entityState == null) {
                entityState = getEntityState(entity, event.getEntityName(), entry, source);
            }
            switch(entityState) {
                case DETACHED:
                    entityIsDetached(event, copyCache);
                    break;
                case TRANSIENT:
                    entityIsTransient(event, copyCache);
                    break;
                case PERSISTENT:
                    entityIsPersistent(event, copyCache);
                    break;
                default:
                    //DELETED
                    throw new ObjectDeletedException("deleted instance passed to merge", null, getLoggableName(event.getEntityName(), entity));
            }
        }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) EntityKey(org.hibernate.engine.spi.EntityKey) EventSource(org.hibernate.event.spi.EventSource) LazyInitializer(org.hibernate.proxy.LazyInitializer) EntityEntry(org.hibernate.engine.spi.EntityEntry) Serializable(java.io.Serializable) ObjectDeletedException(org.hibernate.ObjectDeletedException) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Aggregations

EventSource (org.hibernate.event.spi.EventSource)36 EntityPersister (org.hibernate.persister.entity.EntityPersister)15 Serializable (java.io.Serializable)10 EntityEntry (org.hibernate.engine.spi.EntityEntry)10 EntityKey (org.hibernate.engine.spi.EntityKey)8 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)7 PostLoadEvent (org.hibernate.event.spi.PostLoadEvent)5 HibernateProxy (org.hibernate.proxy.HibernateProxy)4 AssertionFailure (org.hibernate.AssertionFailure)3 HibernateException (org.hibernate.HibernateException)3 Status (org.hibernate.engine.spi.Status)3 PreLoadEvent (org.hibernate.event.spi.PreLoadEvent)3 CollectionPersister (org.hibernate.persister.collection.CollectionPersister)3 Type (org.hibernate.type.Type)3 TransientObjectException (org.hibernate.TransientObjectException)2 PersistentCollection (org.hibernate.collection.spi.PersistentCollection)2 CascadePoint (org.hibernate.engine.internal.CascadePoint)2 StatefulPersistenceContext (org.hibernate.engine.internal.StatefulPersistenceContext)2 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)2 EventType (org.hibernate.event.spi.EventType)2