Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.internal;

import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.SessionImpl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
* Operations to instantiate and (de)serialize {@link StatefulPersistenceContext}
* without exposing the class outside this package.
*
* @author Gavin King
*/
public class PersistenceContexts {
public static PersistenceContext createPersistenceContext(SharedSessionContractImplementor session) {
return new StatefulPersistenceContext( session );
}

public static PersistenceContext deserialize(ObjectInputStream ois, SessionImpl session)
throws IOException, ClassNotFoundException {
return StatefulPersistenceContext.deserialize( ois, session );
}

public static void serialize(PersistenceContext persistenceContext, ObjectOutputStream oos)
throws IOException {
( (StatefulPersistenceContext) persistenceContext ).serialize( oos );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
* @author Steve Ebersole
* @author Sanne Grinovero
*/
public class StatefulPersistenceContext implements PersistenceContext {
class StatefulPersistenceContext implements PersistenceContext {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
MethodHandles.lookup(),
CoreMessageLogger.class,
Expand Down Expand Up @@ -173,7 +173,7 @@ the following fields are used in all circumstances, and are not worth (or not su
*
* @param session The session "owning" this context.
*/
public StatefulPersistenceContext(SharedSessionContractImplementor session) {
StatefulPersistenceContext(SharedSessionContractImplementor session) {
this.session = session;
this.entityEntryContext = new EntityEntryContext( this );
}
Expand Down Expand Up @@ -430,7 +430,7 @@ public EntityHolder claimEntityHolderIfPossible(
}

@Override
public @Nullable EntityHolderImpl getEntityHolder(EntityKey key) {
public @Nullable EntityHolder getEntityHolder(EntityKey key) {
return entitiesByKey == null ? null : entitiesByKey.get( key );
}

Expand Down Expand Up @@ -535,7 +535,7 @@ public boolean containsEntity(EntityKey key) {

@Override
public Object removeEntity(EntityKey key) {
final EntityHolderImpl holder = removeEntityHolder( key );
final EntityHolderImpl holder = removeHolder( key );
if ( holder != null ) {
final Object entity = holder.entity;
if ( holder.proxy != null ) {
Expand All @@ -549,7 +549,11 @@ public Object removeEntity(EntityKey key) {
}

@Override
public @Nullable EntityHolderImpl removeEntityHolder(EntityKey key) {
public @Nullable EntityHolder removeEntityHolder(EntityKey key) {
return removeHolder( key );
}

private EntityHolderImpl removeHolder(EntityKey key) {
final EntityHolderImpl holder;
if ( entitiesByKey != null ) {
holder = entitiesByKey.remove( key );
Expand Down Expand Up @@ -1423,10 +1427,12 @@ public void setFlushing(boolean flushing) {
}
}

public boolean isRemovingOrphanBeforeUpates() {
@Override
public boolean isRemovingOrphanBeforeUpdates() {
return removeOrphanBeforeUpdatesCounter > 0;
}

@Override
public void beginRemoveOrphanBeforeUpdates() {
if ( getCascadeLevel() < 1 ) {
throw new IllegalStateException( "Attempt to remove orphan when not cascading." );
Expand All @@ -1443,6 +1449,7 @@ public void beginRemoveOrphanBeforeUpdates() {
removeOrphanBeforeUpdatesCounter++;
}

@Override
public void endRemoveOrphanBeforeUpdates() {
if ( getCascadeLevel() < 1 ) {
throw new IllegalStateException( "Finished removing orphan when not cascading." );
Expand Down Expand Up @@ -2317,7 +2324,7 @@ public NaturalIdResolutions getNaturalIdResolutions() {

@Override
public EntityHolder detachEntity(EntityKey key) {
final EntityHolderImpl entityHolder = removeEntityHolder( key );
final EntityHolderImpl entityHolder = removeHolder( key );
if ( entityHolder != null ) {
entityHolder.state = EntityHolderState.DETACHED;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,12 @@ EntityHolder claimEntityHolderIfPossible(
*/
void setReadOnly(Object entityOrProxy, boolean readOnly);

boolean isRemovingOrphanBeforeUpdates();

void beginRemoveOrphanBeforeUpdates();

void endRemoveOrphanBeforeUpdates();

void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Object generatedId);

@Internal
Expand Down Expand Up @@ -856,10 +862,9 @@ EntityHolder claimEntityHolderIfPossible(
NaturalIdResolutions getNaturalIdResolutions();

/**
Remove the {@link EntityHolder} and set its state to DETACHED
Remove the {@link EntityHolder} and set its state to {@code DETACHED}.
*/
default @Nullable EntityHolder detachEntity(EntityKey key) {
EntityHolder entityHolder = removeEntityHolder( key );
return entityHolder;
return removeEntityHolder( key );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;

import static org.hibernate.pretty.MessageHelper.infoString;
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;

/**
* Defines the default evict event listener used by hibernate for evicting entities
Expand All @@ -48,7 +48,7 @@ public void onEvict(EvictEvent event) throws HibernateException {
if ( object == null ) {
throw new NullPointerException( "null passed to Session.evict()" );
}
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
final LazyInitializer lazyInitializer = extractLazyInitializer( object );
if ( lazyInitializer != null ) {
final Object id = lazyInitializer.getInternalIdentifier();
if ( id == null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
import org.hibernate.UnresolvableObjectException;
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.StatefulPersistenceContext;
import org.hibernate.engine.internal.PersistenceContexts;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.env.internal.NonContextualLobCreator;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
Expand Down Expand Up @@ -217,7 +217,7 @@
* session, and such actions are executed asynchronously when the session is {@linkplain #flush flushed}. The
* motivation behind this architecture is two-fold: first, it enables customization by sophisticated extensions to
* Hibernate ORM, and, second, it enables the transactional write-behind semantics of a stateful session. The stateful
* session holds its state in an instance of {@link StatefulPersistenceContext}, which we may view as the first-level
* session holds its state in an instance of {@code StatefulPersistenceContext}, which we may view as the first-level
* cache associated with the session.
*
* @author Gavin King
Expand All @@ -238,7 +238,7 @@ public class SessionImpl

private transient ActionQueue actionQueue;
private transient EventListenerGroups eventListenerGroups;
private transient StatefulPersistenceContext persistenceContext;
private transient PersistenceContext persistenceContext;

private transient LoadQueryInfluencers loadQueryInfluencers;

Expand Down Expand Up @@ -313,8 +313,8 @@ private FlushMode getInitialFlushMode() {
: ConfigurationHelper.getFlushMode( getSessionProperty( HINT_FLUSH_MODE ), FlushMode.AUTO );
}

protected StatefulPersistenceContext createPersistenceContext() {
return new StatefulPersistenceContext( this );
protected PersistenceContext createPersistenceContext() {
return PersistenceContexts.createPersistenceContext( this );
}

protected ActionQueue createActionQueue() {
Expand Down Expand Up @@ -864,7 +864,7 @@ private void fireMerge(final MergeContext mergeContext, final MergeEvent event)
@Override
public void delete(String entityName, Object object, boolean isCascadeDeleteEnabled, DeleteContext transientEntities) {
checkOpenOrWaitingForAutoClose();
final boolean removingOrphanBeforeUpdates = persistenceContext.isRemovingOrphanBeforeUpates();
final boolean removingOrphanBeforeUpdates = persistenceContext.isRemovingOrphanBeforeUpdates();
final boolean traceEnabled = log.isTraceEnabled();
if ( traceEnabled && removingOrphanBeforeUpdates ) {
logRemoveOrphanBeforeUpdates( "before continuing", entityName, object );
Expand Down Expand Up @@ -2992,7 +2992,7 @@ private void writeObject(ObjectOutputStream oos) throws IOException {

oos.defaultWriteObject();

persistenceContext.serialize( oos );
PersistenceContexts.serialize( persistenceContext, oos );
actionQueue.serialize( oos );

oos.writeObject( loadQueryInfluencers );
Expand All @@ -3014,7 +3014,7 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound

ois.defaultReadObject();

persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
persistenceContext = PersistenceContexts.deserialize( ois, this );
actionQueue = ActionQueue.deserialize( ois, this );

loadQueryInfluencers = (LoadQueryInfluencers) ois.readObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.StatefulPersistenceContext;
import org.hibernate.engine.internal.PersistenceContexts;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.EffectiveEntityGraph;
import org.hibernate.engine.spi.EntityHolder;
Expand Down Expand Up @@ -115,7 +115,7 @@
* cannot, unfortunately, reuse the various {@link org.hibernate.action.internal.EntityAction} subtypes. This is
* a pity, since it results in some code duplication. On the other hand, a {@code StatelessSession} is easier to
* debug and understand. A {@code StatelessSession} does hold state in a long-lived {@link PersistenceContext},
* but it does temporarily keep state within an instance of {@link StatefulPersistenceContext} while processing
* but it does temporarily keep state within an instance of {@code StatefulPersistenceContext} while processing
* the results of a given query.
*
* @author Gavin King
Expand All @@ -134,7 +134,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
public StatelessSessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
super( factory, options );
connectionProvided = options.getConnection() != null;
temporaryPersistenceContext = new StatefulPersistenceContext( this );
temporaryPersistenceContext = PersistenceContexts.createPersistenceContext( this );
influencers = new LoadQueryInfluencers( getFactory() );
eventListenerGroups = factory.getEventListenerGroups();
setUpMultitenancy( factory, influencers );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.engine.internal.ImmutableEntityEntryFactory;
import org.hibernate.engine.internal.MutableEntityEntryFactory;
import org.hibernate.engine.internal.StatefulPersistenceContext;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.profile.internal.FetchProfileAffectee;
import org.hibernate.engine.spi.CachedNaturalIdValueSource;
Expand Down Expand Up @@ -3853,15 +3852,18 @@ private void handleNaturalIdReattachment(Object entity, SharedSessionContractImp
// for reattachment of mutable natural-ids, we absolutely positively have to grab the snapshot from the
// database, because we have no other way to know if the state changed while detached.
final Object[] entitySnapshot = persistenceContext.getDatabaseSnapshot( id, this );
final Object naturalIdSnapshot = entitySnapshot == StatefulPersistenceContext.NO_ROW
? null
: naturalIdMapping.extractNaturalIdFromEntityState( entitySnapshot );
final Object naturalIdSnapshot = naturalIdFromSnapshot( entitySnapshot );

naturalIdResolutions.removeSharedResolution( id, naturalIdSnapshot, this, false );
final Object naturalId = naturalIdMapping.extractNaturalIdFromEntity( entity );
naturalIdResolutions.manageLocalResolution( id, naturalId, this, CachedNaturalIdValueSource.UPDATE );
}

private Object naturalIdFromSnapshot(Object[] entitySnapshot) {
return entitySnapshot == PersistenceContext.NO_ROW ? null
: naturalIdMapping.extractNaturalIdFromEntityState( entitySnapshot );
}

@Override
public Boolean isTransient(Object entity, SharedSessionContractImplementor session) throws HibernateException {
final Object id = getIdentifier( entity, session );
Expand Down
Loading