Search in sources :

Example 71 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class DefaultLoadEventListener method createProxyIfNecessary.

/**
	 * If there is already a corresponding proxy associated with the
	 * persistence context, return it; otherwise create a proxy, associate it
	 * with the persistence context, and return the just-created proxy.
	 *
	 * @param event The initiating load request event
	 * @param persister The persister corresponding to the entity to be loaded
	 * @param keyToLoad The key of the entity to be loaded
	 * @param options The defined load options
	 * @param persistenceContext The originating session
	 *
	 * @return The created/existing proxy
	 */
private Object createProxyIfNecessary(final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options, final PersistenceContext persistenceContext) {
    Object existing = persistenceContext.getEntity(keyToLoad);
    if (existing != null) {
        // return existing object or initialized proxy (unless deleted)
        if (traceEnabled) {
            LOG.trace("Entity found in session cache");
        }
        if (options.isCheckDeleted()) {
            EntityEntry entry = persistenceContext.getEntry(existing);
            Status status = entry.getStatus();
            if (status == Status.DELETED || status == Status.GONE) {
                return null;
            }
        }
        return existing;
    }
    if (traceEnabled) {
        LOG.trace("Creating new proxy for entity");
    }
    // return new uninitialized proxy
    Object proxy = persister.createProxy(event.getEntityId(), event.getSession());
    persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad);
    persistenceContext.addProxy(keyToLoad, proxy);
    return proxy;
}
Also used : Status(org.hibernate.engine.spi.Status) EntityEntry(org.hibernate.engine.spi.EntityEntry)

Example 72 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class DefaultSaveOrUpdateEventListener method entityIsPersistent.

protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException {
    final boolean traceEnabled = LOG.isTraceEnabled();
    if (traceEnabled) {
        LOG.trace("Ignoring persistent instance");
    }
    EntityEntry entityEntry = event.getEntry();
    if (entityEntry == null) {
        throw new AssertionFailure("entity was transient or detached");
    } else {
        if (entityEntry.getStatus() == Status.DELETED) {
            throw new AssertionFailure("entity was deleted");
        }
        final SessionFactoryImplementor factory = event.getSession().getFactory();
        Serializable requestedId = event.getRequestedId();
        Serializable savedId;
        if (requestedId == null) {
            savedId = entityEntry.getId();
        } else {
            final boolean isEqual = !entityEntry.getPersister().getIdentifierType().isEqual(requestedId, entityEntry.getId(), factory);
            if (isEqual) {
                throw new PersistentObjectException("object passed to save() was already persistent: " + MessageHelper.infoString(entityEntry.getPersister(), requestedId, factory));
            }
            savedId = requestedId;
        }
        if (traceEnabled) {
            LOG.tracev("Object already associated with session: {0}", MessageHelper.infoString(entityEntry.getPersister(), savedId, factory));
        }
        return savedId;
    }
}
Also used : EntityEntry(org.hibernate.engine.spi.EntityEntry) Serializable(java.io.Serializable) AssertionFailure(org.hibernate.AssertionFailure) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) PersistentObjectException(org.hibernate.PersistentObjectException)

Example 73 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class Loader method initializeEntitiesAndCollections.

private void initializeEntitiesAndCollections(final List hydratedObjects, final Object resultSetId, final SharedSessionContractImplementor session, final boolean readOnly, List<AfterLoadAction> afterLoadActions) throws HibernateException {
    final CollectionPersister[] collectionPersisters = getCollectionPersisters();
    if (collectionPersisters != null) {
        for (CollectionPersister collectionPersister : collectionPersisters) {
            if (collectionPersister.isArray()) {
                //for arrays, we should end the collection load beforeQuery resolving
                //the entities, since the actual array instances are not instantiated
                //during loading
                //TODO: or we could do this polymorphically, and have two
                //      different operations implemented differently for arrays
                endCollectionLoad(resultSetId, session, collectionPersister);
            }
        }
    }
    //important: reuse the same event instances for performance!
    final PreLoadEvent pre;
    final PostLoadEvent post;
    if (session.isEventSource()) {
        pre = new PreLoadEvent((EventSource) session);
        post = new PostLoadEvent((EventSource) session);
    } else {
        pre = null;
        post = null;
    }
    if (hydratedObjects != null) {
        int hydratedObjectsSize = hydratedObjects.size();
        LOG.tracev("Total objects hydrated: {0}", hydratedObjectsSize);
        for (Object hydratedObject : hydratedObjects) {
            TwoPhaseLoad.initializeEntity(hydratedObject, readOnly, session, pre);
        }
    }
    if (collectionPersisters != null) {
        for (CollectionPersister collectionPersister : collectionPersisters) {
            if (!collectionPersister.isArray()) {
                //for sets, we should end the collection load afterQuery resolving
                //the entities, since we might call hashCode() on the elements
                //TODO: or we could do this polymorphically, and have two
                //      different operations implemented differently for arrays
                endCollectionLoad(resultSetId, session, collectionPersister);
            }
        }
    }
    // persistence context.
    if (hydratedObjects != null) {
        for (Object hydratedObject : hydratedObjects) {
            TwoPhaseLoad.postLoad(hydratedObject, session, post);
            if (afterLoadActions != null) {
                for (AfterLoadAction afterLoadAction : afterLoadActions) {
                    final EntityEntry entityEntry = session.getPersistenceContext().getEntry(hydratedObject);
                    if (entityEntry == null) {
                        // big problem
                        throw new HibernateException("Could not locate EntityEntry immediately afterQuery two-phase load");
                    }
                    afterLoadAction.afterLoad(session, hydratedObject, (Loadable) entityEntry.getPersister());
                }
            }
        }
    }
}
Also used : PostLoadEvent(org.hibernate.event.spi.PostLoadEvent) EventSource(org.hibernate.event.spi.EventSource) EntityEntry(org.hibernate.engine.spi.EntityEntry) CollectionPersister(org.hibernate.persister.collection.CollectionPersister) HibernateException(org.hibernate.HibernateException) AfterLoadAction(org.hibernate.loader.spi.AfterLoadAction) PreLoadEvent(org.hibernate.event.spi.PreLoadEvent)

Example 74 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class EntityUpdateAction method execute.

@Override
public void execute() throws HibernateException {
    final Serializable id = getId();
    final EntityPersister persister = getPersister();
    final SharedSessionContractImplementor session = getSession();
    final Object instance = getInstance();
    final boolean veto = preUpdate();
    final SessionFactoryImplementor factory = session.getFactory();
    Object previousVersion = this.previousVersion;
    if (persister.isVersionPropertyGenerated()) {
        // we need to grab the version value from the entity, otherwise
        // we have issues with generated-version entities that may have
        // multiple actions queued during the same flush
        previousVersion = persister.getVersion(instance);
    }
    final Object ck;
    if (persister.hasCache()) {
        final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
        ck = cache.generateCacheKey(id, persister, factory, session.getTenantIdentifier());
        lock = cache.lockItem(session, ck, previousVersion);
    } else {
        ck = null;
    }
    if (!veto) {
        persister.update(id, state, dirtyFields, hasDirtyCollection, previousState, previousVersion, instance, rowId, session);
    }
    final EntityEntry entry = session.getPersistenceContext().getEntry(instance);
    if (entry == null) {
        throw new AssertionFailure("possible nonthreadsafe access to session");
    }
    if (entry.getStatus() == Status.MANAGED || persister.isVersionPropertyGenerated()) {
        // get the updated snapshot of the entity state by cloning current state;
        // it is safe to copy in place, since by this time no-one else (should have)
        // has a reference  to the array
        TypeHelper.deepCopy(state, persister.getPropertyTypes(), persister.getPropertyCheckability(), state, session);
        if (persister.hasUpdateGeneratedProperties()) {
            // this entity defines proeprty generation, so process those generated
            // values...
            persister.processUpdateGeneratedProperties(id, instance, state, session);
            if (persister.isVersionPropertyGenerated()) {
                nextVersion = Versioning.getVersion(state, persister);
            }
        }
        // have the entity entry doAfterTransactionCompletion post-update processing, passing it the
        // update state and the new version (if one).
        entry.postUpdate(instance, state, nextVersion);
    }
    if (persister.hasCache()) {
        if (persister.isCacheInvalidationRequired() || entry.getStatus() != Status.MANAGED) {
            persister.getCacheAccessStrategy().remove(session, ck);
        } else if (session.getCacheMode().isPutEnabled()) {
            //TODO: inefficient if that cache is just going to ignore the updated state!
            final CacheEntry ce = persister.buildCacheEntry(instance, state, nextVersion, getSession());
            cacheEntry = persister.getCacheEntryStructure().structure(ce);
            final boolean put = cacheUpdate(persister, previousVersion, ck);
            if (put && factory.getStatistics().isStatisticsEnabled()) {
                factory.getStatistics().secondLevelCachePut(getPersister().getCacheAccessStrategy().getRegion().getName());
            }
        }
    }
    session.getPersistenceContext().getNaturalIdHelper().manageSharedNaturalIdCrossReference(persister, id, state, previousNaturalIdValues, CachedNaturalIdValueSource.UPDATE);
    postUpdate();
    if (factory.getStatistics().isStatisticsEnabled() && !veto) {
        factory.getStatistics().updateEntity(getPersister().getEntityName());
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) EntityEntry(org.hibernate.engine.spi.EntityEntry) AssertionFailure(org.hibernate.AssertionFailure) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) EntityRegionAccessStrategy(org.hibernate.cache.spi.access.EntityRegionAccessStrategy) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) CacheEntry(org.hibernate.cache.spi.entry.CacheEntry)

Example 75 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class AbstractPersistentCollection method getOrphans.

/**
	 * Given a collection of entity instances that used to
	 * belong to the collection, and a collection of instances
	 * that currently belong, return a collection of orphans
	 */
@SuppressWarnings({ "JavaDoc", "unchecked" })
protected static Collection getOrphans(Collection oldElements, Collection currentElements, String entityName, SharedSessionContractImplementor session) throws HibernateException {
    // short-circuit(s)
    if (currentElements.size() == 0) {
        // no new elements, the old list contains only Orphans
        return oldElements;
    }
    if (oldElements.size() == 0) {
        // no old elements, so no Orphans neither
        return oldElements;
    }
    final EntityPersister entityPersister = session.getFactory().getEntityPersister(entityName);
    final Type idType = entityPersister.getIdentifierType();
    final boolean useIdDirect = mayUseIdDirect(idType);
    // create the collection holding the Orphans
    final Collection res = new ArrayList();
    // collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access
    final java.util.Set currentIds = new HashSet();
    final java.util.Set currentSaving = new IdentitySet();
    for (Object current : currentElements) {
        if (current != null && ForeignKeys.isNotTransient(entityName, current, null, session)) {
            final EntityEntry ee = session.getPersistenceContext().getEntry(current);
            if (ee != null && ee.getStatus() == Status.SAVING) {
                currentSaving.add(current);
            } else {
                final Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, current, session);
                currentIds.add(useIdDirect ? currentId : new TypedValue(idType, currentId));
            }
        }
    }
    // iterate over the *old* list
    for (Object old : oldElements) {
        if (!currentSaving.contains(old)) {
            final Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, old, session);
            if (!currentIds.contains(useIdDirect ? oldId : new TypedValue(idType, oldId))) {
                res.add(old);
            }
        }
    }
    return res;
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) IdentitySet(org.hibernate.internal.util.collections.IdentitySet) ArrayList(java.util.ArrayList) PostgresUUIDType(org.hibernate.type.PostgresUUIDType) UUIDBinaryType(org.hibernate.type.UUIDBinaryType) CompositeType(org.hibernate.type.CompositeType) IntegerType(org.hibernate.type.IntegerType) StringType(org.hibernate.type.StringType) LongType(org.hibernate.type.LongType) UUIDCharType(org.hibernate.type.UUIDCharType) Type(org.hibernate.type.Type) EntityEntry(org.hibernate.engine.spi.EntityEntry) PersistentCollection(org.hibernate.collection.spi.PersistentCollection) Collection(java.util.Collection) MarkerObject(org.hibernate.internal.util.MarkerObject) HashSet(java.util.HashSet) TypedValue(org.hibernate.engine.spi.TypedValue)

Aggregations

EntityEntry (org.hibernate.engine.spi.EntityEntry)79 Serializable (java.io.Serializable)22 EntityPersister (org.hibernate.persister.entity.EntityPersister)21 Session (org.hibernate.Session)18 Test (org.junit.Test)17 CollectionEntry (org.hibernate.engine.spi.CollectionEntry)16 AbstractPersistentCollection (org.hibernate.collection.internal.AbstractPersistentCollection)12 EntityKey (org.hibernate.engine.spi.EntityKey)12 TestForIssue (org.hibernate.testing.TestForIssue)12 AssertionFailure (org.hibernate.AssertionFailure)11 HibernateProxy (org.hibernate.proxy.HibernateProxy)11 HibernateException (org.hibernate.HibernateException)10 EventSource (org.hibernate.event.spi.EventSource)9 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)8 TransientObjectException (org.hibernate.TransientObjectException)7 PersistentCollection (org.hibernate.collection.spi.PersistentCollection)7 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)6 Status (org.hibernate.engine.spi.Status)6 LazyInitializer (org.hibernate.proxy.LazyInitializer)6 EntityRegionAccessStrategy (org.hibernate.cache.spi.access.EntityRegionAccessStrategy)5