Search in sources :

Example 51 with EntityPersister

use of org.hibernate.persister.entity.EntityPersister 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 52 with EntityPersister

use of org.hibernate.persister.entity.EntityPersister in project hibernate-orm by hibernate.

the class DefaultFlushEntityEventListener method dirtyCheck.

/**
	 * Perform a dirty check, and attach the results to the event
	 */
protected void dirtyCheck(final FlushEntityEvent event) throws HibernateException {
    final Object entity = event.getEntity();
    final Object[] values = event.getPropertyValues();
    final SessionImplementor session = event.getSession();
    final EntityEntry entry = event.getEntityEntry();
    final EntityPersister persister = entry.getPersister();
    final Serializable id = entry.getId();
    final Object[] loadedState = entry.getLoadedState();
    int[] dirtyProperties = session.getInterceptor().findDirty(entity, id, values, loadedState, persister.getPropertyNames(), persister.getPropertyTypes());
    if (dirtyProperties == null) {
        if (entity instanceof SelfDirtinessTracker) {
            if (((SelfDirtinessTracker) entity).$$_hibernate_hasDirtyAttributes()) {
                dirtyProperties = persister.resolveAttributeIndexes(((SelfDirtinessTracker) entity).$$_hibernate_getDirtyAttributes());
            } else {
                dirtyProperties = new int[0];
            }
        } else {
            // see if the custom dirtiness strategy can tell us...
            class DirtyCheckContextImpl implements CustomEntityDirtinessStrategy.DirtyCheckContext {

                int[] found;

                @Override
                public void doDirtyChecking(CustomEntityDirtinessStrategy.AttributeChecker attributeChecker) {
                    found = new DirtyCheckAttributeInfoImpl(event).visitAttributes(attributeChecker);
                    if (found != null && found.length == 0) {
                        found = null;
                    }
                }
            }
            DirtyCheckContextImpl context = new DirtyCheckContextImpl();
            session.getFactory().getCustomEntityDirtinessStrategy().findDirty(entity, persister, (Session) session, context);
            dirtyProperties = context.found;
        }
    }
    event.setDatabaseSnapshot(null);
    final boolean interceptorHandledDirtyCheck;
    boolean cannotDirtyCheck;
    if (dirtyProperties == null) {
        // Interceptor returned null, so do the dirtycheck ourself, if possible
        try {
            session.getEventListenerManager().dirtyCalculationStart();
            interceptorHandledDirtyCheck = false;
            // object loaded by update()
            cannotDirtyCheck = loadedState == null;
            if (!cannotDirtyCheck) {
                // dirty check against the usual snapshot of the entity
                dirtyProperties = persister.findDirty(values, loadedState, entity, session);
            } else if (entry.getStatus() == Status.DELETED && !event.getEntityEntry().isModifiableEntity()) {
                // fields should be updated.
                if (values != entry.getDeletedState()) {
                    throw new IllegalStateException("Entity has status Status.DELETED but values != entry.getDeletedState");
                }
                // Even if loadedState == null, we can dirty-check by comparing currentState and
                // entry.getDeletedState() because the only fields to be updated are those that
                // refer to transient entities that are being set to null.
                // - currentState contains the entity's current property values.
                // - entry.getDeletedState() contains the entity's current property values with
                //   references to transient entities set to null.
                // - dirtyProperties will only contain properties that refer to transient entities
                final Object[] currentState = persister.getPropertyValues(event.getEntity());
                dirtyProperties = persister.findDirty(entry.getDeletedState(), currentState, entity, session);
                cannotDirtyCheck = false;
            } else {
                // dirty check against the database snapshot, if possible/necessary
                final Object[] databaseSnapshot = getDatabaseSnapshot(session, persister, id);
                if (databaseSnapshot != null) {
                    dirtyProperties = persister.findModified(databaseSnapshot, values, entity, session);
                    cannotDirtyCheck = false;
                    event.setDatabaseSnapshot(databaseSnapshot);
                }
            }
        } finally {
            session.getEventListenerManager().dirtyCalculationEnd(dirtyProperties != null);
        }
    } else {
        // the Interceptor handled the dirty checking
        cannotDirtyCheck = false;
        interceptorHandledDirtyCheck = true;
    }
    logDirtyProperties(id, dirtyProperties, persister);
    event.setDirtyProperties(dirtyProperties);
    event.setDirtyCheckHandledByInterceptor(interceptorHandledDirtyCheck);
    event.setDirtyCheckPossible(!cannotDirtyCheck);
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) SelfDirtinessTracker(org.hibernate.engine.spi.SelfDirtinessTracker) EntityEntry(org.hibernate.engine.spi.EntityEntry) SessionImplementor(org.hibernate.engine.spi.SessionImplementor)

Example 53 with EntityPersister

use of org.hibernate.persister.entity.EntityPersister 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)

Example 54 with EntityPersister

use of org.hibernate.persister.entity.EntityPersister in project hibernate-orm by hibernate.

the class DefaultPersistEventListener method entityIsPersistent.

@SuppressWarnings({ "unchecked" })
protected void entityIsPersistent(PersistEvent event, Map createCache) {
    LOG.trace("Ignoring persistent instance");
    final EventSource source = event.getSession();
    //TODO: check that entry.getIdentifier().equals(requestedId)
    final Object entity = source.getPersistenceContext().unproxy(event.getObject());
    final EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
    if (createCache.put(entity, entity) == null) {
        justCascade(createCache, source, entity, persister);
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) EventSource(org.hibernate.event.spi.EventSource)

Example 55 with EntityPersister

use of org.hibernate.persister.entity.EntityPersister in project hibernate-orm by hibernate.

the class DefaultPostLoadEventListener method onPostLoad.

@Override
public void onPostLoad(PostLoadEvent event) {
    final Object entity = event.getEntity();
    final EntityEntry entry = event.getSession().getPersistenceContext().getEntry(entity);
    if (entry == null) {
        throw new AssertionFailure("possible non-threadsafe access to the session");
    }
    final LockMode lockMode = entry.getLockMode();
    if (LockMode.PESSIMISTIC_FORCE_INCREMENT.equals(lockMode)) {
        final EntityPersister persister = entry.getPersister();
        final Object nextVersion = persister.forceVersionIncrement(entry.getId(), entry.getVersion(), event.getSession());
        entry.forceLocked(entity, nextVersion);
    } else if (LockMode.OPTIMISTIC_FORCE_INCREMENT.equals(lockMode)) {
        final EntityIncrementVersionProcess incrementVersion = new EntityIncrementVersionProcess(entity, entry);
        event.getSession().getActionQueue().registerProcess(incrementVersion);
    } else if (LockMode.OPTIMISTIC.equals(lockMode)) {
        final EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess(entity, entry);
        event.getSession().getActionQueue().registerProcess(verifyVersion);
    }
    if (event.getPersister().implementsLifecycle()) {
        //log.debug( "calling onLoad()" );
        ((Lifecycle) event.getEntity()).onLoad(event.getSession(), event.getId());
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) EntityEntry(org.hibernate.engine.spi.EntityEntry) AssertionFailure(org.hibernate.AssertionFailure) EntityVerifyVersionProcess(org.hibernate.action.internal.EntityVerifyVersionProcess) Lifecycle(org.hibernate.classic.Lifecycle) LockMode(org.hibernate.LockMode) EntityIncrementVersionProcess(org.hibernate.action.internal.EntityIncrementVersionProcess)

Aggregations

EntityPersister (org.hibernate.persister.entity.EntityPersister)166 Test (org.junit.Test)59 Serializable (java.io.Serializable)34 Session (org.hibernate.Session)31 Type (org.hibernate.type.Type)29 EntityEntry (org.hibernate.engine.spi.EntityEntry)21 EventSource (org.hibernate.event.spi.EventSource)15 EntityRegionAccessStrategy (org.hibernate.cache.spi.access.EntityRegionAccessStrategy)13 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)13 TestForIssue (org.hibernate.testing.TestForIssue)13 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)12 SequenceStyleGenerator (org.hibernate.id.enhanced.SequenceStyleGenerator)12 EntityType (org.hibernate.type.EntityType)12 ArrayList (java.util.ArrayList)11 CompositeType (org.hibernate.type.CompositeType)11 HibernateProxy (org.hibernate.proxy.HibernateProxy)10 PreparedStatement (java.sql.PreparedStatement)8 List (java.util.List)8 EntityKey (org.hibernate.engine.spi.EntityKey)8 QueryParameters (org.hibernate.engine.spi.QueryParameters)8