Search in sources :

Example 91 with EntityEntry

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

the class Collections method processDereferencedCollection.

private static void processDereferencedCollection(PersistentCollection coll, SessionImplementor session) {
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    final CollectionEntry entry = persistenceContext.getCollectionEntry(coll);
    final CollectionPersister loadedPersister = entry.getLoadedPersister();
    if (loadedPersister != null && LOG.isDebugEnabled()) {
        LOG.debugf("Collection dereferenced: %s", MessageHelper.collectionInfoString(loadedPersister, coll, entry.getLoadedKey(), session));
    }
    // do a check
    final boolean hasOrphanDelete = loadedPersister != null && loadedPersister.hasOrphanDelete();
    if (hasOrphanDelete) {
        Serializable ownerId = loadedPersister.getOwnerEntityPersister().getIdentifier(coll.getOwner(), session);
        if (ownerId == null) {
            // the persistence context
            if (session.getFactory().getSessionFactoryOptions().isIdentifierRollbackEnabled()) {
                final EntityEntry ownerEntry = persistenceContext.getEntry(coll.getOwner());
                if (ownerEntry != null) {
                    ownerId = ownerEntry.getId();
                }
            }
            if (ownerId == null) {
                throw new AssertionFailure("Unable to determine collection owner identifier for orphan-delete processing");
            }
        }
        final EntityKey key = session.generateEntityKey(ownerId, loadedPersister.getOwnerEntityPersister());
        final Object owner = persistenceContext.getEntity(key);
        if (owner == null) {
            throw new AssertionFailure("collection owner not associated with session: " + loadedPersister.getRole());
        }
        final EntityEntry e = persistenceContext.getEntry(owner);
        // only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
        if (e != null && e.getStatus() != Status.DELETED && e.getStatus() != Status.GONE) {
            throw new HibernateException("A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: " + loadedPersister.getRole());
        }
    }
    // do the work
    entry.setCurrentPersister(null);
    entry.setCurrentKey(null);
    prepareCollectionForUpdate(coll, entry, session.getFactory());
}
Also used : EntityKey(org.hibernate.engine.spi.EntityKey) Serializable(java.io.Serializable) EntityEntry(org.hibernate.engine.spi.EntityEntry) CollectionEntry(org.hibernate.engine.spi.CollectionEntry) CollectionPersister(org.hibernate.persister.collection.CollectionPersister) AssertionFailure(org.hibernate.AssertionFailure) HibernateException(org.hibernate.HibernateException) PersistenceContext(org.hibernate.engine.spi.PersistenceContext)

Example 92 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 93 with EntityEntry

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

the class DefaultLoadEventListener method loadFromSessionCache.

/**
 * Attempts to locate the entity in the session-level cache.
 * <p/>
 * If allowed to return nulls, then if the entity happens to be found in
 * the session cache, we check the entity type for proper handling
 * of entity hierarchies.
 * <p/>
 * If checkDeleted was set to true, then if the entity is found in the
 * session-level cache, it's current status within the session cache
 * is checked to see if it has previously been scheduled for deletion.
 *
 * @param event The load event
 * @param keyToLoad The EntityKey representing the entity to be loaded.
 * @param options The load options.
 *
 * @return The entity from the session-level cache, or null.
 *
 * @throws HibernateException Generally indicates problems applying a lock-mode.
 */
protected Object loadFromSessionCache(final LoadEvent event, final EntityKey keyToLoad, final LoadEventListener.LoadType options) throws HibernateException {
    SessionImplementor session = event.getSession();
    Object old = session.getEntityUsingInterceptor(keyToLoad);
    if (old != null) {
        // this object was already loaded
        EntityEntry oldEntry = session.getPersistenceContext().getEntry(old);
        if (options.isCheckDeleted()) {
            Status status = oldEntry.getStatus();
            if (status == Status.DELETED || status == Status.GONE) {
                return REMOVED_ENTITY_MARKER;
            }
        }
        if (options.isAllowNulls()) {
            final EntityPersister persister = event.getSession().getFactory().getEntityPersister(keyToLoad.getEntityName());
            if (!persister.isInstance(old)) {
                return INCONSISTENT_RTN_CLASS_MARKER;
            }
        }
        upgradeLock(old, oldEntry, event.getLockOptions(), event.getSession());
    }
    return old;
}
Also used : Status(org.hibernate.engine.spi.Status) EntityPersister(org.hibernate.persister.entity.EntityPersister) EntityEntry(org.hibernate.engine.spi.EntityEntry) SessionImplementor(org.hibernate.engine.spi.SessionImplementor)

Example 94 with EntityEntry

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

the class AbstractEntityPersister method delete.

/**
 * Delete an object
 */
public void delete(Serializable id, Object version, Object object, SharedSessionContractImplementor session) throws HibernateException {
    final int span = getTableSpan();
    boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() && isAllOrDirtyOptLocking();
    Object[] loadedState = null;
    if (isImpliedOptimisticLocking) {
        // need to treat this as if it where optimistic-lock="all" (dirty does *not* make sense);
        // first we need to locate the "loaded" state
        // 
        // Note, it potentially could be a proxy, so doAfterTransactionCompletion the location the safe way...
        final EntityKey key = session.generateEntityKey(id, this);
        Object entity = session.getPersistenceContext().getEntity(key);
        if (entity != null) {
            EntityEntry entry = session.getPersistenceContext().getEntry(entity);
            loadedState = entry.getLoadedState();
        }
    }
    final String[] deleteStrings;
    if (isImpliedOptimisticLocking && loadedState != null) {
        // we need to utilize dynamic delete statements
        deleteStrings = generateSQLDeletStrings(loadedState);
    } else {
        // otherwise, utilize the static delete statements
        deleteStrings = getSQLDeleteStrings();
    }
    for (int j = span - 1; j >= 0; j--) {
        delete(id, version, j, object, deleteStrings[j], session, loadedState);
    }
}
Also used : EntityKey(org.hibernate.engine.spi.EntityKey) EntityEntry(org.hibernate.engine.spi.EntityEntry)

Example 95 with EntityEntry

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

the class MessageHelper method collectionInfoString.

// collections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
 * Generate an info message string relating to a particular managed
 * collection.  Attempts to intelligently handle property-refs issues
 * where the collection key is not the same as the owner key.
 *
 * @param persister The persister for the collection
 * @param collection The collection itself
 * @param collectionKey The collection key
 * @param session The session
 * @return An info string, in the form [Foo.bars#1]
 */
public static String collectionInfoString(CollectionPersister persister, PersistentCollection collection, Serializable collectionKey, SharedSessionContractImplementor session) {
    StringBuilder s = new StringBuilder();
    s.append('[');
    if (persister == null) {
        s.append("<unreferenced>");
    } else {
        s.append(persister.getRole());
        s.append('#');
        Type ownerIdentifierType = persister.getOwnerEntityPersister().getIdentifierType();
        Serializable ownerKey;
        // or is always using the owner id sufficient?
        if (collectionKey.getClass().isAssignableFrom(ownerIdentifierType.getReturnedClass())) {
            ownerKey = collectionKey;
        } else {
            Object collectionOwner = collection == null ? null : collection.getOwner();
            EntityEntry entry = collectionOwner == null ? null : session.getPersistenceContext().getEntry(collectionOwner);
            ownerKey = entry == null ? null : entry.getId();
        }
        s.append(ownerIdentifierType.toLoggableString(ownerKey, session.getFactory()));
    }
    s.append(']');
    return s.toString();
}
Also used : Type(org.hibernate.type.Type) Serializable(java.io.Serializable) EntityEntry(org.hibernate.engine.spi.EntityEntry)

Aggregations

EntityEntry (org.hibernate.engine.spi.EntityEntry)140 EntityPersister (org.hibernate.persister.entity.EntityPersister)34 CollectionEntry (org.hibernate.engine.spi.CollectionEntry)28 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)27 TestForIssue (org.hibernate.testing.TestForIssue)26 Test (org.junit.Test)23 EntityKey (org.hibernate.engine.spi.EntityKey)22 Session (org.hibernate.Session)19 HibernateProxy (org.hibernate.proxy.HibernateProxy)18 Test (org.junit.jupiter.api.Test)18 EventSource (org.hibernate.event.spi.EventSource)16 HibernateException (org.hibernate.HibernateException)13 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)13 Serializable (java.io.Serializable)12 AbstractPersistentCollection (org.hibernate.collection.internal.AbstractPersistentCollection)12 AbstractPersistentCollection (org.hibernate.collection.spi.AbstractPersistentCollection)12 AssertionFailure (org.hibernate.AssertionFailure)11 Type (org.hibernate.type.Type)11 PersistentCollection (org.hibernate.collection.spi.PersistentCollection)10 Status (org.hibernate.engine.spi.Status)10