Search in sources :

Example 1 with ForeignGenerator

use of org.hibernate.id.ForeignGenerator 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, PersistContext 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.getPersistenceContextInternal().getEntry(entity);
    EntityState entityState = EntityState.getEntityState(entity, entityName, entityEntry, source, true);
    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
        final EntityPersister persister = source.getFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(entityName);
        if (persister.getIdentifierGenerator() instanceof ForeignGenerator) {
            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 = EntityState.getEntityState(entity, entityName, entityEntry, source, true);
        }
    }
    switch(entityState) {
        case DETACHED:
            {
                throw new PersistentObjectException("detached entity passed to persist: " + EventUtil.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, EventUtil.getLoggableName(event.getEntityName(), entity));
            }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) LazyInitializer(org.hibernate.proxy.LazyInitializer) EntityEntry(org.hibernate.engine.spi.EntityEntry) ForeignGenerator(org.hibernate.id.ForeignGenerator) SessionImplementor(org.hibernate.engine.spi.SessionImplementor) ObjectDeletedException(org.hibernate.ObjectDeletedException) PersistentObjectException(org.hibernate.PersistentObjectException) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Example 2 with ForeignGenerator

use of org.hibernate.id.ForeignGenerator in project hibernate-reactive by hibernate.

the class DefaultReactivePersistEventListener method reactiveOnPersist.

/**
 * Handle the given create event.
 *
 * @param event The create event to be handled.
 */
public CompletionStage<Void> reactiveOnPersist(PersistEvent event, IdentitySet 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 voidFuture();
            } else {
                return failedFuture(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.getPersistenceContextInternal().getEntry(entity);
    EntityState entityState = EntityState.getEntityState(entity, entityName, entityEntry, source, true);
    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().getMetamodel().entityPersister(entityName);
        if (persister.getIdentifierGenerator() instanceof ForeignGenerator) {
            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 = EntityState.getEntityState(entity, entityName, entityEntry, source, true);
        }
    }
    switch(entityState) {
        case DETACHED:
            {
                return failedFuture(new PersistentObjectException("detached entity passed to persist: " + EventUtil.getLoggableName(event.getEntityName(), entity)));
            }
        case PERSISTENT:
            {
                return entityIsPersistent(event, createCache);
            }
        case TRANSIENT:
            {
                return entityIsTransient(event, createCache);
            }
        case DELETED:
            {
                entityEntry.setStatus(Status.MANAGED);
                entityEntry.setDeletedState(null);
                event.getSession().getActionQueue().unScheduleDeletion(entityEntry, event.getObject());
                return entityIsDeleted(event, createCache);
            }
        default:
            {
                return failedFuture(new ObjectDeletedException("deleted entity passed to persist", null, EventUtil.getLoggableName(event.getEntityName(), entity)));
            }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) LazyInitializer(org.hibernate.proxy.LazyInitializer) EntityEntry(org.hibernate.engine.spi.EntityEntry) ForeignGenerator(org.hibernate.id.ForeignGenerator) SessionImplementor(org.hibernate.engine.spi.SessionImplementor) ObjectDeletedException(org.hibernate.ObjectDeletedException) MessageHelper.infoString(org.hibernate.pretty.MessageHelper.infoString) EntityState(org.hibernate.event.internal.EntityState) PersistentObjectException(org.hibernate.PersistentObjectException) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Aggregations

ObjectDeletedException (org.hibernate.ObjectDeletedException)2 PersistentObjectException (org.hibernate.PersistentObjectException)2 EntityEntry (org.hibernate.engine.spi.EntityEntry)2 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)2 ForeignGenerator (org.hibernate.id.ForeignGenerator)2 EntityPersister (org.hibernate.persister.entity.EntityPersister)2 HibernateProxy (org.hibernate.proxy.HibernateProxy)2 LazyInitializer (org.hibernate.proxy.LazyInitializer)2 EntityState (org.hibernate.event.internal.EntityState)1 MessageHelper.infoString (org.hibernate.pretty.MessageHelper.infoString)1