Search in sources :

Example 1 with PersistentObjectException

use of org.hibernate.PersistentObjectException in project hibernate-orm by hibernate.

the class DefaultLoadEventListener method load.

/**
 * Performs the load of an entity.
 *
 * @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
 *
 * @return The loaded entity.
 *
 * @throws HibernateException
 */
private Object load(final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options) {
    if (event.getInstanceToLoad() != null) {
        if (event.getSession().getPersistenceContext().getEntry(event.getInstanceToLoad()) != null) {
            throw new PersistentObjectException("attempted to load into an instance that was already associated with the session: " + MessageHelper.infoString(persister, event.getEntityId(), event.getSession().getFactory()));
        }
        persister.setIdentifier(event.getInstanceToLoad(), event.getEntityId(), event.getSession());
    }
    final Object entity = doLoad(event, persister, keyToLoad, options);
    boolean isOptionalInstance = event.getInstanceToLoad() != null;
    if (entity == null && (!options.isAllowNulls() || isOptionalInstance)) {
        event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound(event.getEntityClassName(), event.getEntityId());
    } else if (isOptionalInstance && entity != event.getInstanceToLoad()) {
        throw new NonUniqueObjectException(event.getEntityId(), event.getEntityClassName());
    }
    return entity;
}
Also used : NonUniqueObjectException(org.hibernate.NonUniqueObjectException) PersistentObjectException(org.hibernate.PersistentObjectException)

Example 2 with PersistentObjectException

use of org.hibernate.PersistentObjectException in project hibernate-orm by hibernate.

the class DefaultRefreshEventListener method onRefresh.

/**
 * Handle the given refresh event.
 *
 * @param event The refresh event to be handled.
 */
public void onRefresh(RefreshEvent event, Map refreshedAlready) {
    final EventSource source = event.getSession();
    boolean isTransient;
    if (event.getEntityName() != null) {
        isTransient = !source.contains(event.getEntityName(), event.getObject());
    } else {
        isTransient = !source.contains(event.getObject());
    }
    if (source.getPersistenceContext().reassociateIfUninitializedProxy(event.getObject())) {
        if (isTransient) {
            source.setReadOnly(event.getObject(), source.isDefaultReadOnly());
        }
        return;
    }
    final Object object = source.getPersistenceContext().unproxyAndReassociate(event.getObject());
    if (refreshedAlready.containsKey(object)) {
        LOG.trace("Already refreshed");
        return;
    }
    final EntityEntry e = source.getPersistenceContext().getEntry(object);
    final EntityPersister persister;
    final Serializable id;
    if (e == null) {
        persister = source.getEntityPersister(event.getEntityName(), object);
        // refresh() does not pass an entityName
        id = persister.getIdentifier(object, event.getSession());
        if (LOG.isTraceEnabled()) {
            LOG.tracev("Refreshing transient {0}", MessageHelper.infoString(persister, id, source.getFactory()));
        }
        final EntityKey key = source.generateEntityKey(id, persister);
        if (source.getPersistenceContext().getEntry(key) != null) {
            throw new PersistentObjectException("attempted to refresh transient instance when persistent instance was already associated with the Session: " + MessageHelper.infoString(persister, id, source.getFactory()));
        }
    } else {
        if (LOG.isTraceEnabled()) {
            LOG.tracev("Refreshing ", MessageHelper.infoString(e.getPersister(), e.getId(), source.getFactory()));
        }
        if (!e.isExistsInDatabase()) {
            throw new UnresolvableObjectException(e.getId(), "this instance does not yet exist as a row in the database");
        }
        persister = e.getPersister();
        id = e.getId();
    }
    // cascade the refresh prior to refreshing this entity
    refreshedAlready.put(object, object);
    Cascade.cascade(CascadingActions.REFRESH, CascadePoint.BEFORE_REFRESH, source, persister, object, refreshedAlready);
    if (e != null) {
        final EntityKey key = source.generateEntityKey(id, persister);
        source.getPersistenceContext().removeEntity(key);
        if (persister.hasCollections()) {
            new EvictVisitor(source, object).process(object, persister);
        }
    }
    if (persister.canWriteToCache()) {
        Object previousVersion = null;
        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(object);
        }
        final EntityDataAccess cache = persister.getCacheAccessStrategy();
        final Object ck = cache.generateCacheKey(id, persister, source.getFactory(), source.getTenantIdentifier());
        final SoftLock lock = cache.lockItem(source, ck, previousVersion);
        cache.remove(source, ck);
        source.getActionQueue().registerProcess((success, session) -> cache.unlockItem(session, ck, lock));
    }
    evictCachedCollections(persister, id, source);
    String previousFetchProfile = source.getLoadQueryInfluencers().getInternalFetchProfile();
    source.getLoadQueryInfluencers().setInternalFetchProfile("refresh");
    Object result = persister.load(id, object, event.getLockOptions(), source);
    // If it was transient, then set it to the default for the source.
    if (result != null) {
        if (!persister.isMutable()) {
            // this is probably redundant; it should already be read-only
            source.setReadOnly(result, true);
        } else {
            source.setReadOnly(result, (e == null ? source.isDefaultReadOnly() : e.isReadOnly()));
        }
    }
    source.getLoadQueryInfluencers().setInternalFetchProfile(previousFetchProfile);
    UnresolvableObjectException.throwIfNull(result, id, persister.getEntityName());
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) PersistentObjectException(org.hibernate.PersistentObjectException) EntityKey(org.hibernate.engine.spi.EntityKey) EventSource(org.hibernate.event.spi.EventSource) EntityEntry(org.hibernate.engine.spi.EntityEntry) UnresolvableObjectException(org.hibernate.UnresolvableObjectException) EntityDataAccess(org.hibernate.cache.spi.access.EntityDataAccess) SoftLock(org.hibernate.cache.spi.access.SoftLock)

Example 3 with PersistentObjectException

use of org.hibernate.PersistentObjectException 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 4 with PersistentObjectException

use of org.hibernate.PersistentObjectException in project hibernate-orm by hibernate.

the class StatefulPersistenceContext method unproxy.

@Override
public Object unproxy(Object maybeProxy) throws HibernateException {
    if (maybeProxy instanceof HibernateProxy) {
        final HibernateProxy proxy = (HibernateProxy) maybeProxy;
        final LazyInitializer li = proxy.getHibernateLazyInitializer();
        if (li.isUninitialized()) {
            throw new PersistentObjectException("object was an uninitialized proxy for " + li.getEntityName());
        }
        // unwrap the object and return
        return li.getImplementation();
    } else {
        return maybeProxy;
    }
}
Also used : LazyInitializer(org.hibernate.proxy.LazyInitializer) PersistentObjectException(org.hibernate.PersistentObjectException) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Example 5 with PersistentObjectException

use of org.hibernate.PersistentObjectException in project hibernate-orm by hibernate.

the class DefaultPersistEventListener method onPersist.

/**
 * Handle the given create event.
 *
 * @param event The create event to be handled.
 */
public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
    final SessionImplementor source = event.getSession();
    final Object object = event.getObject();
    final Object entity;
    if (object instanceof HibernateProxy) {
        LazyInitializer li = ((HibernateProxy) object).getHibernateLazyInitializer();
        if (li.isUninitialized()) {
            if (li.getSession() == source) {
                // NOTE EARLY EXIT!
                return;
            } else {
                throw new PersistentObjectException("uninitialized proxy passed to persist()");
            }
        }
        entity = li.getImplementation();
    } else {
        entity = object;
    }
    final String entityName;
    if (event.getEntityName() != null) {
        entityName = event.getEntityName();
    } else {
        entityName = source.bestGuessEntityName(entity);
        event.setEntityName(entityName);
    }
    final EntityEntry entityEntry = source.getPersistenceContext().getEntry(entity);
    EntityState entityState = getEntityState(entity, entityName, entityEntry, source);
    if (entityState == EntityState.DETACHED) {
        // JPA 2, in its version of a "foreign generated", allows the id attribute value
        // to be manually set by the user, even though this manual value is irrelevant.
        // The issue is that this causes problems with the Hibernate unsaved-value strategy
        // which comes into play here in determining detached/transient state.
        // 
        // Detect if we have this situation and if so null out the id value and calculate the
        // entity state again.
        // NOTE: entityEntry must be null to get here, so we cannot use any of its values
        EntityPersister persister = source.getFactory().getEntityPersister(entityName);
        if (ForeignGenerator.class.isInstance(persister.getIdentifierGenerator())) {
            if (LOG.isDebugEnabled() && persister.getIdentifier(entity, source) != null) {
                LOG.debug("Resetting entity id attribute to null for foreign generator");
            }
            persister.setIdentifier(entity, null, source);
            entityState = getEntityState(entity, entityName, entityEntry, source);
        }
    }
    switch(entityState) {
        case DETACHED:
            {
                throw new PersistentObjectException("detached entity passed to persist: " + getLoggableName(event.getEntityName(), entity));
            }
        case PERSISTENT:
            {
                entityIsPersistent(event, createCache);
                break;
            }
        case TRANSIENT:
            {
                entityIsTransient(event, createCache);
                break;
            }
        case DELETED:
            {
                entityEntry.setStatus(Status.MANAGED);
                entityEntry.setDeletedState(null);
                event.getSession().getActionQueue().unScheduleDeletion(entityEntry, event.getObject());
                entityIsDeleted(event, createCache);
                break;
            }
        default:
            {
                throw new ObjectDeletedException("deleted entity passed to persist", null, getLoggableName(event.getEntityName(), entity));
            }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) LazyInitializer(org.hibernate.proxy.LazyInitializer) EntityEntry(org.hibernate.engine.spi.EntityEntry) SessionImplementor(org.hibernate.engine.spi.SessionImplementor) ObjectDeletedException(org.hibernate.ObjectDeletedException) PersistentObjectException(org.hibernate.PersistentObjectException) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Aggregations

PersistentObjectException (org.hibernate.PersistentObjectException)5 EntityEntry (org.hibernate.engine.spi.EntityEntry)3 Serializable (java.io.Serializable)2 EntityPersister (org.hibernate.persister.entity.EntityPersister)2 HibernateProxy (org.hibernate.proxy.HibernateProxy)2 LazyInitializer (org.hibernate.proxy.LazyInitializer)2 AssertionFailure (org.hibernate.AssertionFailure)1 NonUniqueObjectException (org.hibernate.NonUniqueObjectException)1 ObjectDeletedException (org.hibernate.ObjectDeletedException)1 UnresolvableObjectException (org.hibernate.UnresolvableObjectException)1 EntityDataAccess (org.hibernate.cache.spi.access.EntityDataAccess)1 SoftLock (org.hibernate.cache.spi.access.SoftLock)1 EntityKey (org.hibernate.engine.spi.EntityKey)1 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)1 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)1 EventSource (org.hibernate.event.spi.EventSource)1