Search in sources :

Example 51 with HibernateProxy

use of org.hibernate.proxy.HibernateProxy in project hibernate-orm by hibernate.

the class EntityType method isEqual.

@Override
public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) {
    // associations (many-to-one and one-to-one) can be null...
    if (x == null || y == null) {
        return x == y;
    }
    EntityPersister persister = getAssociatedEntityPersister(factory);
    if (!persister.canExtractIdOutOfEntity()) {
        return super.isEqual(x, y);
    }
    final Class mappedClass = persister.getMappedClass();
    Serializable xid;
    if (x instanceof HibernateProxy) {
        xid = ((HibernateProxy) x).getHibernateLazyInitializer().getIdentifier();
    } else {
        if (mappedClass.isAssignableFrom(x.getClass())) {
            xid = persister.getIdentifier(x);
        } else {
            // JPA 2 case where @IdClass contains the id and not the associated entity
            xid = (Serializable) x;
        }
    }
    Serializable yid;
    if (y instanceof HibernateProxy) {
        yid = ((HibernateProxy) y).getHibernateLazyInitializer().getIdentifier();
    } else {
        if (mappedClass.isAssignableFrom(y.getClass())) {
            yid = persister.getIdentifier(y);
        } else {
            // JPA 2 case where @IdClass contains the id and not the associated entity
            yid = (Serializable) y;
        }
    }
    return persister.getIdentifierType().isEqual(xid, yid, factory);
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Example 52 with HibernateProxy

use of org.hibernate.proxy.HibernateProxy in project hibernate-orm by hibernate.

the class Cascade method cascadeLogicalOneToOneOrphanRemoval.

private static void cascadeLogicalOneToOneOrphanRemoval(final CascadingAction action, final EventSource eventSource, final int componentPathStackDepth, final Object parent, final Object child, final Type type, final CascadeStyle style, final String propertyName, final boolean isCascadeDeleteEnabled) throws HibernateException {
    // potentially we need to handle orphan deletes for one-to-ones here...
    if (isLogicalOneToOne(type)) {
        // orphan checking
        if (style.hasOrphanDelete() && action.deleteOrphans()) {
            // value is orphaned if loaded state for this property shows not null
            // because it is currently null.
            final EntityEntry entry = eventSource.getPersistenceContext().getEntry(parent);
            if (entry != null && entry.getStatus() != Status.SAVING) {
                Object loadedValue;
                if (componentPathStackDepth == 0) {
                    // association defined on entity
                    loadedValue = entry.getLoadedValue(propertyName);
                } else {
                    // association defined on component
                    // todo : this is currently unsupported because of the fact that
                    // we do not know the loaded state of this value properly
                    // and doing so would be very difficult given how components and
                    // entities are loaded (and how 'loaded state' is put into the
                    // EntityEntry).  Solutions here are to either:
                    // 1) properly account for components as a 2-phase load construct
                    // 2) just assume the association was just now orphaned and
                    // issue the orphan delete.  This would require a special
                    // set of SQL statements though since we do not know the
                    // orphaned value, something a delete with a subquery to
                    // match the owner.
                    // final EntityType entityType = (EntityType) type;
                    // final String getPropertyPath = composePropertyPath( entityType.getPropertyName() );
                    loadedValue = null;
                }
                // entity is managed (without first nulling and manually flushing).
                if (child == null || (loadedValue != null && child != loadedValue)) {
                    EntityEntry valueEntry = eventSource.getPersistenceContext().getEntry(loadedValue);
                    if (valueEntry == null && loadedValue instanceof HibernateProxy) {
                        // un-proxy and re-associate for cascade operation
                        // useful for @OneToOne defined as FetchType.LAZY
                        loadedValue = eventSource.getPersistenceContext().unproxyAndReassociate(loadedValue);
                        valueEntry = eventSource.getPersistenceContext().getEntry(loadedValue);
                        // associated one-to-one.
                        if (child == loadedValue) {
                            // do nothing
                            return;
                        }
                    }
                    if (valueEntry != null) {
                        final String entityName = valueEntry.getPersister().getEntityName();
                        if (LOG.isTraceEnabled()) {
                            final Serializable id = valueEntry.getPersister().getIdentifier(loadedValue, eventSource);
                            final String description = MessageHelper.infoString(entityName, id);
                            LOG.tracev("Deleting orphaned entity instance: {0}", description);
                        }
                        if (type.isAssociationType() && ((AssociationType) type).getForeignKeyDirection().equals(ForeignKeyDirection.TO_PARENT)) {
                            // If FK direction is to-parent, we must remove the orphan *before* the queued update(s)
                            // occur.  Otherwise, replacing the association on a managed entity, without manually
                            // nulling and flushing, causes FK constraint violations.
                            eventSource.removeOrphanBeforeUpdates(entityName, loadedValue);
                        } else {
                            // Else, we must delete after the updates.
                            eventSource.delete(entityName, loadedValue, isCascadeDeleteEnabled, new HashSet());
                        }
                    }
                }
            }
        }
    }
}
Also used : EntityEntry(org.hibernate.engine.spi.EntityEntry) Serializable(java.io.Serializable) AssociationType(org.hibernate.type.AssociationType) HibernateProxy(org.hibernate.proxy.HibernateProxy) HashSet(java.util.HashSet)

Example 53 with HibernateProxy

use of org.hibernate.proxy.HibernateProxy in project hibernate-orm by hibernate.

the class DefaultLoadEventListener method returnNarrowedProxy.

/**
 * Given a proxy, initialize it and/or narrow it provided either
 * is necessary.
 *
 * @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
 * @param proxy The proxy to narrow
 *
 * @return The created/existing proxy
 */
private Object returnNarrowedProxy(final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options, final PersistenceContext persistenceContext, final Object proxy) {
    if (traceEnabled) {
        LOG.trace("Entity proxy found in session cache");
    }
    LazyInitializer li = ((HibernateProxy) proxy).getHibernateLazyInitializer();
    if (li.isUnwrap()) {
        return li.getImplementation();
    }
    Object impl = null;
    if (!options.isAllowProxyCreation()) {
        impl = load(event, persister, keyToLoad, options);
        if (impl == null) {
            event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound(persister.getEntityName(), keyToLoad.getIdentifier());
        }
    }
    return persistenceContext.narrowProxy(proxy, persister, keyToLoad, impl);
}
Also used : LazyInitializer(org.hibernate.proxy.LazyInitializer) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Example 54 with HibernateProxy

use of org.hibernate.proxy.HibernateProxy in project hibernate-orm by hibernate.

the class DefaultLoadEventListener method assembleCacheEntry.

private Object assembleCacheEntry(final StandardCacheEntryImpl entry, final Serializable id, final EntityPersister persister, final LoadEvent event) throws HibernateException {
    final Object optionalObject = event.getInstanceToLoad();
    final EventSource session = event.getSession();
    final SessionFactoryImplementor factory = session.getFactory();
    if (traceEnabled) {
        LOG.tracev("Assembling entity from second-level cache: {0}", MessageHelper.infoString(persister, id, factory));
    }
    EntityPersister subclassPersister = factory.getEntityPersister(entry.getSubclass());
    Object result = optionalObject == null ? session.instantiate(subclassPersister, id) : optionalObject;
    // make it circular-reference safe
    final EntityKey entityKey = session.generateEntityKey(id, subclassPersister);
    TwoPhaseLoad.addUninitializedCachedEntity(entityKey, result, subclassPersister, LockMode.NONE, entry.getVersion(), session);
    Type[] types = subclassPersister.getPropertyTypes();
    Object[] values = entry.assemble(result, id, subclassPersister, session.getInterceptor(), session);
    // intializes result by side-effect
    TypeHelper.deepCopy(values, types, subclassPersister.getPropertyUpdateability(), values, session);
    Object version = Versioning.getVersion(values, subclassPersister);
    LOG.tracev("Cached Version: {0}", version);
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    boolean isReadOnly = session.isDefaultReadOnly();
    if (persister.isMutable()) {
        Object proxy = persistenceContext.getProxy(entityKey);
        if (proxy != null) {
            // there is already a proxy for this impl
            // only set the status to read-only if the proxy is read-only
            isReadOnly = ((HibernateProxy) proxy).getHibernateLazyInitializer().isReadOnly();
        }
    } else {
        isReadOnly = true;
    }
    persistenceContext.addEntry(result, (isReadOnly ? Status.READ_ONLY : Status.MANAGED), values, null, id, version, LockMode.NONE, true, subclassPersister, false);
    subclassPersister.afterInitialize(result, session);
    persistenceContext.initializeNonLazyCollections();
    // upgrade the lock if necessary:
    // lock(result, lockMode);
    // PostLoad is needed for EJB3
    // TODO: reuse the PostLoadEvent...
    PostLoadEvent postLoadEvent = event.getPostLoadEvent().setEntity(result).setId(id).setPersister(persister);
    for (PostLoadEventListener listener : postLoadEventListeners(session)) {
        listener.onPostLoad(postLoadEvent);
    }
    return result;
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) PostLoadEvent(org.hibernate.event.spi.PostLoadEvent) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) StatefulPersistenceContext(org.hibernate.engine.internal.StatefulPersistenceContext) HibernateProxy(org.hibernate.proxy.HibernateProxy) PostLoadEventListener(org.hibernate.event.spi.PostLoadEventListener) EntityKey(org.hibernate.engine.spi.EntityKey) EventSource(org.hibernate.event.spi.EventSource) EmbeddedComponentType(org.hibernate.type.EmbeddedComponentType) EntityType(org.hibernate.type.EntityType) EventType(org.hibernate.event.spi.EventType) Type(org.hibernate.type.Type)

Example 55 with HibernateProxy

use of org.hibernate.proxy.HibernateProxy 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

HibernateProxy (org.hibernate.proxy.HibernateProxy)130 Session (org.hibernate.Session)58 Test (org.junit.Test)56 LazyInitializer (org.hibernate.proxy.LazyInitializer)33 DefaultPostLoaderDao (org.broadleafcommerce.common.persistence.DefaultPostLoaderDao)16 PostLoaderDao (org.broadleafcommerce.common.persistence.PostLoaderDao)16 EntityEntry (org.hibernate.engine.spi.EntityEntry)13 Serializable (java.io.Serializable)11 Transaction (org.hibernate.Transaction)10 TransientObjectException (org.hibernate.TransientObjectException)10 EntityPersister (org.hibernate.persister.entity.EntityPersister)10 HibernateException (org.hibernate.HibernateException)8 AdminPresentationMergeOverride (org.broadleafcommerce.common.presentation.override.AdminPresentationMergeOverride)5 EntityKey (org.hibernate.engine.spi.EntityKey)4 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)4 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)4 Iterator (java.util.Iterator)3 ObjectDeletedException (org.hibernate.ObjectDeletedException)3 EventSource (org.hibernate.event.spi.EventSource)3 BigDecimal (java.math.BigDecimal)2