Search in sources :

Example 1 with ReactiveSession

use of org.hibernate.reactive.session.ReactiveSession in project hibernate-reactive by hibernate.

the class DefaultReactiveMergeEventListener method fetchAndCopyValues.

private CompletionStage<Void> fetchAndCopyValues(final EntityPersister persister, final Object entity, final Object target, final SessionImplementor source, final MergeContext mergeContext) {
    CompletionStage<Void> stage;
    if (entity == target) {
        // If entity == target, then nothing needs to be fetched.
        stage = voidFuture();
    } else {
        ReactiveSession session = source.unwrap(ReactiveSession.class);
        final Object[] mergeState = persister.getPropertyValues(entity);
        final Object[] managedState = persister.getPropertyValues(target);
        // Cascade-merge mappings do not determine what needs to be fetched.
        // The value only needs to be fetched if the incoming value (mergeState[i])
        // is initialized, but its corresponding managed state is not initialized.
        // Initialization must be done before copyValues() executes.
        stage = loop(0, mergeState.length, i -> Hibernate.isInitialized(mergeState[i]) && !Hibernate.isInitialized(managedState[i]), i -> session.reactiveFetch(managedState[i], true));
    }
    return stage.thenCompose(v -> copyValues(persister, entity, target, source, mergeContext));
}
Also used : CascadingAction(org.hibernate.reactive.engine.impl.CascadingAction) AssertionFailure(org.hibernate.AssertionFailure) EntityPersister(org.hibernate.persister.entity.EntityPersister) EventSource(org.hibernate.event.spi.EventSource) Log(org.hibernate.reactive.logging.impl.Log) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) ForeignKeyDirection(org.hibernate.type.ForeignKeyDirection) MergeEvent(org.hibernate.event.spi.MergeEvent) LoggerFactory(org.hibernate.reactive.logging.impl.LoggerFactory) MergeContext(org.hibernate.event.internal.MergeContext) ObjectDeletedException(org.hibernate.ObjectDeletedException) TO_PARENT(org.hibernate.type.ForeignKeyDirection.TO_PARENT) HibernateProxy(org.hibernate.proxy.HibernateProxy) FROM_PARENT(org.hibernate.type.ForeignKeyDirection.FROM_PARENT) PersistentAttributeInterceptor(org.hibernate.engine.spi.PersistentAttributeInterceptor) Map(java.util.Map) EventUtil(org.hibernate.event.internal.EventUtil) Cascade(org.hibernate.reactive.engine.impl.Cascade) CompletionStages.voidFuture(org.hibernate.reactive.util.impl.CompletionStages.voidFuture) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) ReactiveSession(org.hibernate.reactive.session.ReactiveSession) LazyInitializer(org.hibernate.proxy.LazyInitializer) PersistentAttributeInterceptable(org.hibernate.engine.spi.PersistentAttributeInterceptable) EntityTypes(org.hibernate.reactive.engine.impl.EntityTypes) MethodHandles(java.lang.invoke.MethodHandles) StaleObjectStateException(org.hibernate.StaleObjectStateException) StatisticsImplementor(org.hibernate.stat.spi.StatisticsImplementor) TypeHelper(org.hibernate.type.TypeHelper) EntityKey(org.hibernate.engine.spi.EntityKey) EntityCopyObserver(org.hibernate.event.spi.EntityCopyObserver) ServiceRegistry(org.hibernate.service.ServiceRegistry) Serializable(java.io.Serializable) CompletionStage(java.util.concurrent.CompletionStage) EntityCopyObserverFactory(org.hibernate.event.spi.EntityCopyObserverFactory) ReactiveMergeEventListener(org.hibernate.reactive.event.ReactiveMergeEventListener) MergeEventListener(org.hibernate.event.spi.MergeEventListener) EntityEntry(org.hibernate.engine.spi.EntityEntry) CompletionStages.loop(org.hibernate.reactive.util.impl.CompletionStages.loop) WrongClassException(org.hibernate.WrongClassException) CascadePoint(org.hibernate.engine.internal.CascadePoint) EntityState(org.hibernate.event.internal.EntityState) EnhancementAsProxyLazinessInterceptor(org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor) SessionImplementor(org.hibernate.engine.spi.SessionImplementor) HibernateException(org.hibernate.HibernateException) Hibernate(org.hibernate.Hibernate) SelfDirtinessTracker(org.hibernate.engine.spi.SelfDirtinessTracker) DETACHED(org.hibernate.event.internal.EntityState.DETACHED) ReactiveSession(org.hibernate.reactive.session.ReactiveSession)

Example 2 with ReactiveSession

use of org.hibernate.reactive.session.ReactiveSession in project hibernate-reactive by hibernate.

the class ReactiveAbstractEntityPersister method generateValue.

default CompletionStage<?> generateValue(Object owner, SharedSessionContractImplementor session, InMemoryValueGenerationStrategy valueGenerationStrategy) {
    final ValueGenerator<?> valueGenerator = valueGenerationStrategy.getValueGenerator();
    if (valueGenerator instanceof StageValueGenerator) {
        final StageSessionFactoryImpl stageFactory = new StageSessionFactoryImpl((SessionFactoryImpl) session.getFactory());
        final Stage.Session stageSession = new StageSessionImpl((ReactiveSession) session, stageFactory);
        return ((StageValueGenerator<?>) valueGenerator).generateValue(stageSession, owner);
    }
    if (valueGenerator instanceof MutinyValueGenerator) {
        MutinySessionFactoryImpl mutinyFactory = new MutinySessionFactoryImpl((SessionFactoryImpl) session.getFactory());
        Mutiny.Session mutinySession = new MutinySessionImpl((ReactiveSession) session, mutinyFactory);
        return ((MutinyValueGenerator<?>) valueGenerator).generateValue(mutinySession, owner).subscribeAsCompletionStage();
    }
    // annotations. We need an alternative for Hibernate Reactive.
    return completedFuture(valueGenerationStrategy.getValueGenerator().generateValue((Session) session, owner));
}
Also used : MutinyValueGenerator(org.hibernate.reactive.tuple.MutinyValueGenerator) StageSessionFactoryImpl(org.hibernate.reactive.stage.impl.StageSessionFactoryImpl) StageSessionImpl(org.hibernate.reactive.stage.impl.StageSessionImpl) Mutiny(org.hibernate.reactive.mutiny.Mutiny) CompletionStage(java.util.concurrent.CompletionStage) Stage(org.hibernate.reactive.stage.Stage) MutinySessionImpl(org.hibernate.reactive.mutiny.impl.MutinySessionImpl) StageValueGenerator(org.hibernate.reactive.tuple.StageValueGenerator) MutinySessionFactoryImpl(org.hibernate.reactive.mutiny.impl.MutinySessionFactoryImpl) Session(org.hibernate.Session) ReactiveSession(org.hibernate.reactive.session.ReactiveSession)

Example 3 with ReactiveSession

use of org.hibernate.reactive.session.ReactiveSession in project hibernate-reactive by hibernate.

the class DefaultReactivePostLoadEventListener method onPostLoad.

@Override
public void onPostLoad(PostLoadEvent event) {
    final Object entity = event.getEntity();
    callbackRegistry.postLoad(entity);
    final SessionImplementor session = event.getSession();
    final EntityEntry entry = session.getPersistenceContextInternal().getEntry(entity);
    if (entry == null) {
        throw new AssertionFailure("possible non-threadsafe access to the session");
    }
    LockMode lockMode = entry.getLockMode();
    if (LockMode.OPTIMISTIC_FORCE_INCREMENT.equals(lockMode)) {
        ((ReactiveSession) session).getReactiveActionQueue().registerProcess(new ReactiveEntityIncrementVersionProcess(entity));
    } else if (LockMode.OPTIMISTIC.equals(lockMode)) {
        ((ReactiveSession) session).getReactiveActionQueue().registerProcess(new ReactiveEntityVerifyVersionProcess(entity));
    }
}
Also used : ReactiveSession(org.hibernate.reactive.session.ReactiveSession) EntityEntry(org.hibernate.engine.spi.EntityEntry) AssertionFailure(org.hibernate.AssertionFailure) ReactiveEntityVerifyVersionProcess(org.hibernate.reactive.engine.impl.ReactiveEntityVerifyVersionProcess) SessionImplementor(org.hibernate.engine.spi.SessionImplementor) ReactiveEntityIncrementVersionProcess(org.hibernate.reactive.engine.impl.ReactiveEntityIncrementVersionProcess) LockMode(org.hibernate.LockMode)

Example 4 with ReactiveSession

use of org.hibernate.reactive.session.ReactiveSession in project hibernate-reactive by hibernate.

the class AbstractReactiveSaveEventListener method reactiveSaveWithGeneratedId.

/**
 * Prepares the save call using a newly generated id.
 *
 * @param entity The entity to be saved
 * @param entityName The entity-name for the entity to be saved
 * @param context Generally cascade-specific information.
 * @param source The session which is the source of this save event.
 * @param requiresImmediateIdAccess does the event context require
 * access to the identifier immediately after execution of this method (if
 * not, post-insert style id generators may be postponed if we are outside
 * a transaction).
 *
 * @return The id used to save the entity; may be null depending on the
 * type of id generator used and the requiresImmediateIdAccess value
 */
protected CompletionStage<Void> reactiveSaveWithGeneratedId(Object entity, String entityName, C context, EventSource source, boolean requiresImmediateIdAccess) {
    callbackRegistry.preCreate(entity);
    if (entity instanceof SelfDirtinessTracker) {
        ((SelfDirtinessTracker) entity).$$_hibernate_clearDirtyAttributes();
    }
    EntityPersister persister = source.getEntityPersister(entityName, entity);
    boolean autoincrement = persister.isIdentifierAssignedByInsert();
    return generateId(entity, persister, (ReactiveSession) source, source.getSession()).thenCompose(id -> reactivePerformSave(entity, autoincrement ? null : assignIdIfNecessary(id, entity, persister, source.getSession()), persister, autoincrement, context, source, !autoincrement || requiresImmediateIdAccess));
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) ReactiveSession(org.hibernate.reactive.session.ReactiveSession) SelfDirtinessTracker(org.hibernate.engine.spi.SelfDirtinessTracker)

Example 5 with ReactiveSession

use of org.hibernate.reactive.session.ReactiveSession in project hibernate-reactive by hibernate.

the class Cascade method cascadeLogicalOneToOneOrphanRemoval.

private void cascadeLogicalOneToOneOrphanRemoval(final int componentPathStackDepth, 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 PersistenceContext persistenceContext = eventSource.getPersistenceContextInternal();
            final EntityEntry entry = persistenceContext.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 = persistenceContext.getEntry(loadedValue);
                    if (valueEntry == null && loadedValue instanceof HibernateProxy) {
                        // un-proxy and re-associate for cascade operation
                        // useful for @OneToOne defined as FetchType.LAZY
                        loadedValue = persistenceContext.unproxyAndReassociate(loadedValue);
                        valueEntry = persistenceContext.getEntry(loadedValue);
                        // associated one-to-one.
                        if (child == loadedValue) {
                            // do nothing
                            return;
                        }
                    }
                    if (valueEntry != null) {
                        EntityPersister persister = valueEntry.getPersister();
                        String entityName = persister.getEntityName();
                        if (LOG.isTraceEnabled()) {
                            LOG.tracev("Deleting orphaned entity instance: {0}", infoString(entityName, persister.getIdentifier(loadedValue, eventSource)));
                        }
                        final Object loaded = loadedValue;
                        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.
                            stage = stage.thenCompose(v -> ((ReactiveSession) eventSource).reactiveRemoveOrphanBeforeUpdates(entityName, loaded));
                        } else {
                            // Else, we must delete after the updates.
                            stage = stage.thenCompose(v -> ((ReactiveSession) eventSource).reactiveRemove(entityName, loaded, isCascadeDeleteEnabled, new IdentitySet()));
                        }
                    }
                }
            }
        }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) EntityPersister(org.hibernate.persister.entity.EntityPersister) EventSource(org.hibernate.event.spi.EventSource) CollectionType(org.hibernate.type.CollectionType) CollectionEntry(org.hibernate.engine.spi.CollectionEntry) Log(org.hibernate.reactive.logging.impl.Log) EntityType(org.hibernate.type.EntityType) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) ForeignKeyDirection(org.hibernate.type.ForeignKeyDirection) LoggerFactory(org.hibernate.reactive.logging.impl.LoggerFactory) PersistentCollection(org.hibernate.collection.spi.PersistentCollection) HibernateProxy(org.hibernate.proxy.HibernateProxy) CompositeType(org.hibernate.type.CompositeType) IdentitySet(org.hibernate.internal.util.collections.IdentitySet) LazyAttributeLoadingInterceptor(org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor) Status(org.hibernate.engine.spi.Status) CompletionStages.voidFuture(org.hibernate.reactive.util.impl.CompletionStages.voidFuture) ReactiveSession(org.hibernate.reactive.session.ReactiveSession) Iterator(java.util.Iterator) MethodHandles(java.lang.invoke.MethodHandles) Collection(java.util.Collection) CacheMode(org.hibernate.CacheMode) Objects(java.util.Objects) MessageHelper.infoString(org.hibernate.pretty.MessageHelper.infoString) CompletionStage(java.util.concurrent.CompletionStage) CascadeStyle(org.hibernate.engine.spi.CascadeStyle) EntityEntry(org.hibernate.engine.spi.EntityEntry) CompletionStages.loop(org.hibernate.reactive.util.impl.CompletionStages.loop) CascadePoint(org.hibernate.engine.internal.CascadePoint) HibernateException(org.hibernate.HibernateException) CollectionPersister(org.hibernate.persister.collection.CollectionPersister) AssociationType(org.hibernate.type.AssociationType) Hibernate(org.hibernate.Hibernate) Type(org.hibernate.type.Type) ReactiveSession(org.hibernate.reactive.session.ReactiveSession) EntityEntry(org.hibernate.engine.spi.EntityEntry) AssociationType(org.hibernate.type.AssociationType) IdentitySet(org.hibernate.internal.util.collections.IdentitySet) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) MessageHelper.infoString(org.hibernate.pretty.MessageHelper.infoString) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Aggregations

ReactiveSession (org.hibernate.reactive.session.ReactiveSession)6 CompletionStage (java.util.concurrent.CompletionStage)4 EntityEntry (org.hibernate.engine.spi.EntityEntry)4 EntityPersister (org.hibernate.persister.entity.EntityPersister)4 MethodHandles (java.lang.invoke.MethodHandles)3 Hibernate (org.hibernate.Hibernate)3 HibernateException (org.hibernate.HibernateException)3 CascadePoint (org.hibernate.engine.internal.CascadePoint)3 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)3 EventSource (org.hibernate.event.spi.EventSource)3 HibernateProxy (org.hibernate.proxy.HibernateProxy)3 Log (org.hibernate.reactive.logging.impl.Log)3 LoggerFactory (org.hibernate.reactive.logging.impl.LoggerFactory)3 CompletionStages.loop (org.hibernate.reactive.util.impl.CompletionStages.loop)3 CompletionStages.voidFuture (org.hibernate.reactive.util.impl.CompletionStages.voidFuture)3 ForeignKeyDirection (org.hibernate.type.ForeignKeyDirection)3 Collection (java.util.Collection)2 Iterator (java.util.Iterator)2 Objects (java.util.Objects)2 AssertionFailure (org.hibernate.AssertionFailure)2